版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
题目链接:点击查看
题目大意:两个人在玩游戏,初始时两个人分别有一定数量的牌,牌面的大小一定是互不相同的,游戏规则如下:
每次两个人同时从自己牌堆的最顶端取出一张牌,我们可以记做a和b,比较一下其大小,牌面更大的一方获胜,胜者可以先将对面的牌a放到自己牌堆的下面,然后再将自己b放到牌a下面,如此往复,牌堆先为空的人即输掉了游戏
还有一种情况就是两个人在游戏过程中会出现循环的情况,此时游戏视为平局,输出-1
题目分析:简单模拟,只是单纯的觉得题面挺有意思的,就是英文题面不太友好。。今晚是小师弟给我讲的题意我才实现了的,开两个队列分别模拟两个人的牌,然后一直循环进行游戏即可,因为会有循环的情况出现,这里给出两种方法都可以实现:
- 维护一个map<pair<queue<int>,queue<int>>,bool>vis的map进行判重
- 当游戏的步数大于一个比较大的值时,直接跳出循环即可
我是为了追求完美起见,用了vis进行判重,并且配合了一个mp函数简化了调用make_pair()时的代码量,也算是比较好看的了。。
我看有些老哥是判断游戏步数大于1000时直接跳出循环,这样做可以大大减少空间和时间(map的logn的时间开销),就是有时候可能会先WA上几发(随缘过题法)
废话不多说了,直接上代码吧:
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int N=25;
map<pair<queue<int>,queue<int> >,bool>vis;
queue<int>q1,q2;
pair<queue<int>,queue<int>> mp(queue<int>a,queue<int>b)
{
return make_pair(a,b);
}
int main()
{
int n;
scanf("%d",&n);
int cnt;
scanf("%d",&cnt);
while(cnt--)
{
int num;
scanf("%d",&num);
q1.push(num);
}
scanf("%d",&cnt);
while(cnt--)
{
int num;
scanf("%d",&num);
q2.push(num);
}
bool flag=false;
int ans=0;
vis[mp(q1,q2)]=true;
while(!q1.empty()&&!q2.empty())
{
ans++;
int a=q1.front();
int b=q2.front();
q1.pop();
q2.pop();
if(a>b)
{
q1.push(b);
q1.push(a);
}
else
{
q2.push(a);
q2.push(b);
}
if(vis[mp(q1,q2)])
break;
vis[mp(q1,q2)]=true;
}
if(q1.size()&&q2.size())
printf("-1\n");
else if(!q1.empty())
printf("%d %d\n",ans,1);
else
printf("%d %d\n",ans,2);
return 0;
}