UVA1145 War

· · 题解

模拟题,这里说下实现。

首先,定义 val 数组,用来简便的实现每个牌大小的比较,也就是给每个牌的图案赋个值,使得查询之时可以直接通过后面的值比较大小(见代码中的 init 函数)。

两个玩家的牌堆都可以在底部插入、顶部取出,我们可以很轻易地想到队列实现。

然后每个玩家取出的牌,如果仍未结束战争,则塞到一个栈里面。注意两个元素同时入栈时的顺序。如果一个大一个小,可以结束战争,就不停弹栈到空,把牌加入获胜者的队伍后面。

每回合先塞小牌,再塞入大牌,这样取的时候就能够先取到大牌加入队列,再取到小牌进入队列。

针对 play forever 只需要控制回合数,大于 10^5 就判断成此情况。

最后,出现队列为空时,退出模拟,看是哪个队列空了。其中一个空了就是那个人输了,两个队列都空了是平局。

#include<bits/stdc++.h>
using namespace std;

int val[100];
void init()
{
    val['7']=7,val['8']=8,val['9']=9,
    val['T']=100,val['J']=500,val['Q']=1000,
    val['K']=100000,val['A']=10000000;
}
int stac[36],siz=0;
int main()
{
    init();
    string a,b;
    while(cin>>a>>b)
    {
        siz=0;
        int lun=0;
        queue<int>aa;
        queue<int>bb;
        for(int i=0;i<a.size();i++)
        aa.push(val[a[i]]),
        bb.push(val[b[i]]);
        while(aa.size()&&bb.size())
        {
            if(lun>1e5)
            {
                cout<<"play forever\n";
                break;
            }
            int nowa=aa.front(),nowb=bb.front();
            aa.pop(),bb.pop();
            if(nowa>nowb)
                stac[++siz]=nowb,stac[++siz]=nowa;
            else stac[++siz]=nowa,stac[++siz]=nowb;

            if(nowa>nowb)
                while(siz)
                    aa.push(stac[siz--]);

            else if(nowa<nowb)
                while(siz)
                    bb.push(stac[siz--]);
            lun++;
        }
        if(aa.empty())
            cout<<(bb.empty()?"draw game\n":"B wins\n");
        else if(bb.empty()) cout<<"A wins\n";
    }
    return 0;
}