题目大意:
有一座山,山有h层。每一层都有平台。有些平台凸出来,有些平台是凹进去。主角一开始站在h层平台,他的目标是落到第0层。主角能够下山的方式只有一种:让高为x的平台和高为x-1平台的状态取反从而往下跳。状态取反的意思是:原来是凸凹状态互换。主角每次下落层数必须小于等于2,否则摔死。主角还可以买魔法石,魔法石可以让任意一个石头的状态取反。
问:主角最少需要购买多少个魔法石能够掉到第0层。
解题思路:
我们假设主角一直跳,跳到中间某一层同时此时距离地面的高度非常高。之后我们画连续的1,观看主角的跳下去是否可能摔死。然后我们发现,其实主角每次跳相当于距离-2。然后当连续的1有偶数个时候我们保证主角不会摔死,具体可以数学证明或者画图证明。这里我们从数学来看。主角:跳的距离相当于1+2x那么主角必定最后落在第奇数格,所以主角稳稳地落在最后一格。而当有奇数个1时,主角肯定不能落在最后一格肯定会摔死。所以很自然地,我们可以找到规律,当中间有奇数串时,需要一个魔法石。但是若主角跳到最后一格,且最后一格距离为1时,无论最后一串长度是多少,我们都能落地,这是第一个特判。另外我们也需要考虑主角在第一次跳时候,它是相反为连续偶数个1才会摔死。
废话:
首先找规律的题目,我们必须多去动手尝试,那么是不是完全没套路呢?其实也不是我们需要构造出合理的样例才是突破口,合理的样例比如这里是多个连续排,其它的,我们也可以多动动手比如会不会是奇数啊,偶数啊,质数啊。
在图论中,会不会是一棵树,会不会是一条链,这些常用的样例。
#include <bits/stdc++.h>
#define itn int
using namespace std;
int main(){
int cas;cin>>cas;
while(cas--){
int h,n;cin>>h>>n;
vector<int> mv;
for(int i=0;i<n;i++){
int t;cin>>t;
mv.push_back(t);
}
int ans=0;
int j;
if(h==1){
cout<<0<<endl;
continue;
}
for(int i=0;i<n;i=j){
j=i;
int len=1;
j++;
while(j<n&&(mv[j]==mv[j-1]-1) ){
len++;
j++;
}
if(j==n){
if(mv[n-1]==1)continue;
if(i==0){
if(len%2==0)ans++;
else continue;
}else{if(len%2==1)ans++;
else continue;
}
}
else if(i==0){
if(len%2==0)ans++;
else continue;
}
else if(len%2==1)ans++;
else continue;
}
cout<<ans<<endl;
}
return 0;
}
标签:主角,Free2play,int,codeforces,Standard,++,continue,ans,else From: https://blog.51cto.com/u_15910522/5931527