1. 程式人生 > >翻紙牌遊戲 【HDU

翻紙牌遊戲 【HDU

題目連結

這道題竟是同時改變左右兩個,一開始看成只改變其中一個,然後推了個狀態,發現是偶數就行、奇數就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;
}