翻紙牌遊戲 【HDU
阿新 • • 發佈:2018-12-13
題目連結
這道題竟是同時改變左右兩個,一開始看成只改變其中一個,然後推了個狀態,發現是偶數就行、奇數就NO,後來看到時就知道給WA了,並且還得重新推過。
那麼,這道題又該如何求解?我們知道對於左右兩端是個變數,不如就從左右兩端開始考慮,我以左端作為一個起始來看,無非就是有左端要與不要的情況,若是要走左,就是懂第一個點,a[1]^=1,a[2]^=1,然後在往後判斷,為1點的狀態用後兩個點來改變其;另外一個,就是不動一點,我們就是直接判斷即可.
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef long long ll; const int INF=1e9; const int maxN=25; string s; int cnt=0, ans=0, a[maxN], b[maxN]; int main() { while(cin>>s) { int len=(int)s.size(); ans=INF; if(len==1) { if(s[0]=='1') printf("1\n"); else printf("0\n"); continue; } for(int i=0; i<len; i++) b[i+1]=a[i+1]=(int)(s[i]-'0'); a[1]^=1; a[2]^=1; cnt=1; for(int i=1; i<len; i++) { if(a[i]) { cnt++; a[i]=0; a[i+1]^=1; a[i+2]^=1; } } ans=min(ans, a[len]?INF:cnt); cnt=0; for(int i=1; i<len; i++) { if(b[i]) { cnt++; b[i]=0; b[i+1]^=1; b[i+2]^=1; } } ans=min(ans, b[len]?INF:cnt); if(ans==INF) printf("NO\n"); else printf("%d\n", ans); } return 0; }