代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int bowls[25]; int f[25]; int calc(int k) { memset(f,0,sizeof(f)); int res=0,sum=0; for(int i=0;i<20;i++){ if((bowls[i]+sum)&1){ //对于翻中间动两边的求最值要从两边各来一次 if(i==19){ //对于只要求连续的,就从一边即可 res=30; //因为对于反中间动两边的来说,左到右会翻不到右边倒数第二个,反倒就说明无解 break; //右到左则翻不到右边倒数第二个,这样就造成了差别,可能解不同 } //对于连续来说就不是,左右一样 res++; f[i]=1; } sum+=f[i]; if(i-2>=0){ sum-=f[i-2]; } } memset(f,0,sizeof(f)); int res2=0; int sum2=0; for(int i=19;i>=0;i--){ if((bowls[i]+sum2)&1){ res2++; f[i]=1; if(i==0){ res2=30; break; } } sum2+=f[i]; if(i+2<20){ sum2-=f[i+2]; } } res=min(res,res2); return res; } int main() { while(cin>>bowls[0]){ for(int i=1;i<20;i++){ cin>>bowls[i]; } int n=calc(3); printf("%d\n",n); } return 0; }对于翻中间动两边的求最值要从两边各来一次, 对于只要求连续的,就从一边即可, 因为对于反中间动两边的来说,左到右会翻不到右边倒数第二个,反到就说明无解, 右到左则翻不到右边倒数第二个,这样就造成了差别,可能解不同, 对于连续来说就不是,左右一样