「日常训练」 Soldier and Cards (CFR304D2C)

题意 (Codeforces 546C)

按照指定的规则打牌,问谁胜或无穷尽。

分析

又是一条模拟,用set+queue(这里手写了)处理即可。注意到两种局势“1 234”和“123 4”的差别,所以用set处理的时候需要在两方手牌中间加上相关的分割符号以示区分。

代码

#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define QUICKIO                  
    ios::sync_with_stdio(false); 
    cin.tie(0);                  
    cout.tie(0);
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pi = pair<int,int>;

int carda[1005],cardb[1005];
int aStart=0,aEnd=0,bStart=0,bEnd=0;

set<string> s;
bool addStatus()
{
    string str="";
    for(int i=aStart;i!=aEnd;++i)
        str+='0'+carda[i];
    str+=" "; // important here!
    for(int i=bStart;i!=bEnd;++i)
        str+='0'+cardb[i];
//    cout<<str<<endl;
    if(s.find(str)!=s.end()) return false;
    else
    {
        s.insert(str);
        return true;
    }
}
int isEnd()//1 a win 0 not End -1 b win
{
    if(aStart>=aEnd) return -1;
    else if(bStart>=bEnd) return 1;
    else return 0;
}
int main()
{
    int n; cin>>n;
    int k1; cin>>k1;
    rep(i,1,k1)
    {
        cin>>carda[aEnd++];
    }
    int k2; cin>>k2;
    rep(i,1,k2)
    {
        cin>>cardb[bEnd++];
    }
    int cnt=0;
    while(isEnd()==0 && addStatus())
    {
        int aTop=carda[aStart++],bTop=cardb[bStart++];
        if(aTop>bTop)
        {
            carda[aEnd++]=bTop;
            carda[aEnd++]=aTop;
        }
        else
        {
            cardb[bEnd++]=aTop;
            cardb[bEnd++]=bTop;
        }
        cnt++;
    }
    if(isEnd()==0)
    {
        cout<<-1<<endl;
    }
    else cout<<cnt<<" "<<int(isEnd()==1?1:2)<<endl;

    return 0;
}
如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。
原文地址:https://www.cnblogs.com/samhx/p/9652069.html