ZCMU-1201フリップカードゲーム

トピック

1201:カードフリップゲームの
制限時間:1秒メモリ制限:128 MB
送信:168解決済み:51
[送信] [ステータス] [ウェブボード]
説明
非常に興味深いカードゲームの種類があります。Nを差し上げます。カードが一列に並んでいます。、カードには表と裏があります。開始カードは混沌とした状態になっている可能性があります(表向き、裏返し)。次に、これらのカードを並べ替える必要があります。しかし、問題は、あなたがカードを(前から後ろに、または逆から前に)回すときはいつでも、彼は左右に2枚のカードを持っていることです(左端と右端のカードは近くのカードにのみ影響します)。 、そして今度はあなたに混沌とした状態を与え、各カードが表向きになるようにそれらを配置できるかどうか尋ねます。そうであれば、少なくともいくつの操作が必要です。

入力に
は複数のケースがあります。それぞれの場合に、01記号文字列(長さが1000を超えない)の行を入力します。1は裏面が上を向いていることを意味し、0は前面が上を向いていることを意味します。

出力の
場合ごとに、フリップできる場合は最小数のフリップを出力し、そうでない場合はNOを出力します。

サンプル入力

01
011
1111

サンプル出力
NO

1
2

HINT
は、操作が何であっても、テストデータの最初のセットを完了することができません。

テストデータの2番目のセットでは、右端のカードを1回だけ反転する必要があります。

テストデータの3番目のセットでは、最初と最後のカードを裏返す必要があります

***入力にはscanf( "%s"、s)を使用してください。gets()を使用すると問題が発生する可能性があります。


考え

この問題では、最初にいくつかの発見をシミュレートします。すべて0を達成する場合は、前の発見がすべて0であることを確認しますが、前の発見は1であるため、iを反転すると、i-1 i i + 1 (もしあれば))すべて0になることができます。言い換えれば、それが反転できるかどうかの判断は、前のものが1であるかどうかに依存します。
次に、最初のフロップを異なるカテゴリーで議論する必要があるかどうかに注意する必要があります

ACコード

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x)
const double PI = acos(-1);
const int maxn = 110;
const int mod = 1000000007;
typedef long long ll;
char s[1010];
int turn[1010],Nturn[1010];
int cnt1,cnt2;
//第一张就动
void first_move(int n){
    
    
    cnt1 = 1;
    //动就动1,2张
    turn[0] = -turn[0];
    turn[1] = -turn[1];
    for(int i=1;i<n;++i)
    {
    
    
        if(turn[i-1]==1){
    
    
            cnt1 ++;
            turn[i-1] = -turn[i-1];
            turn[i] = -turn[i];
            if(i!=n-1)turn[i+1] = - turn[i+1];
        }
    }
    if(turn[n-1]==1)cnt1 = -1;
}

//第一张不动
void first_notmove(int n){
    
    
    
    for(int i=1;i<n;++i)
    {
    
    
        if(Nturn[i-1]==1){
    
    
            cnt2 ++;
            Nturn[i-1] = -Nturn[i-1];
            Nturn[i] = -Nturn[i];
            if(i!=n-1)Nturn[i+1] = -Nturn[i+1];
        }
    }
    if(Nturn[n-1]==1)cnt2 = -1;
}

int main()
{
    
    
    while(~scanf("%s",s))
    {
    
    
        cnt1 = cnt2 = 0;
        int len = (int)strlen(s);
        //特别判断len=1
        if(len==1){
    
    
            if(s[0]=='1')printf("1\n");
            else printf("0\n");
        }else
        {
    
    
            for(int i=0;i<len;++i){
    
    
                if(s[i]=='0')turn[i] = -1;
                else turn[i] = 1;
                Nturn[i] = turn[i];
            }
            first_move(len);
            first_notmove(len);
           // cout << cnt1 << " " << cnt2 << endl;
            if(cnt1==-1&&cnt2!=-1){
    
    
                printf("%d\n",cnt2);
                continue;
            }
            if(cnt2==-1&&cnt1!=-1){
    
    
                printf("%d\n",cnt1);
                continue;
            }
            if(cnt1==-1&&cnt2==-1){
    
    
                printf("NO\n");
                continue;
            }
            printf("%d\n",min(cnt1,cnt2));
        }
        memset(turn, 0, sizeof turn);
        memset(Nturn, 0, sizeof Nturn);
        memset(s, 0, sizeof s);
    }
    return 0;
}




総括する

もっとコードを書くのに時間をかけてください、ねえ...

おすすめ

転載: blog.csdn.net/DAVID3A/article/details/115220958