CodeForces - 546C Soldier and Cards(模拟)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_45458915/article/details/102693367

题目链接:点击查看

题目大意:两个人在玩游戏,初始时两个人分别有一定数量的牌,牌面的大小一定是互不相同的,游戏规则如下:

每次两个人同时从自己牌堆的最顶端取出一张牌,我们可以记做a和b,比较一下其大小,牌面更大的一方获胜,胜者可以先将对面的牌a放到自己牌堆的下面,然后再将自己b放到牌a下面,如此往复,牌堆先为空的人即输掉了游戏

还有一种情况就是两个人在游戏过程中会出现循环的情况,此时游戏视为平局,输出-1

题目分析:简单模拟,只是单纯的觉得题面挺有意思的,就是英文题面不太友好。。今晚是小师弟给我讲的题意我才实现了的,开两个队列分别模拟两个人的牌,然后一直循环进行游戏即可,因为会有循环的情况出现,这里给出两种方法都可以实现:

  1. 维护一个map<pair<queue<int>,queue<int>>,bool>vis的map进行判重
  2. 当游戏的步数大于一个比较大的值时,直接跳出循环即可

我是为了追求完美起见,用了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;
}

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/102693367