admin管理员组

文章数量:1621658

题目:
星期天小A和小B约在一起玩桌游,他们在玩一个非常古怪的扑克游戏—“小猫游戏”。游戏的规则是这样的:将一副扑克牌平均分成两份,每个人拿一份。小A先拿出手中的第一张扑克牌放在桌子上,然后将小B也拿出手中的第一张扑克牌,并放在小A刚打出的扑克牌的上面,就像这样俩个仁交替出牌。出牌时,如果某人打出牌与桌面上的牌面相同,即可将俩张相同的牌及其中间所夹得牌全部取走,并依次放到自己手中得最后,当任意一个人手中的牌全部出完时,游戏结束,对手获胜。
假如游戏开始时,小A手中有6张牌,顺序为2 4 1 2 5 6,小B手中也有6张牌,顺序为3 1 3 5 6 4,最终谁会获胜呢?
要求
接下来请你写一个自动判断谁将获胜的程序,这里我们做一个规定,小A 和小B 手中的牌面只有1~9。
题目分析
小A有2种操作,分别是出牌和赢牌。这相当于队列的2个操作,出牌就是出队,赢牌就是入队。小B的操作和小A是一样的。桌子就像一个栈,没打出一个牌就相当于入栈,有人赢牌的时候将牌拿走相当于出栈。那么如何知道桌子上面已经有哪些牌呢?最简单的方法就是枚举桌子上面的每一张牌。

  • 1、首先先创建一个结构体用来实现队列、栈
struct queue{
	int data[1000]; #data存储队列中的元素
	int head;
	int tail;
};
#再创一个结构体来实现栈
struct stack{
   int data[10];  #data用来存储栈中的元素
   int top;#top存储栈顶
};
#定义2个队列q1和q2,q1表示小A手中的牌,q2表示小B手中的牌。定义一个栈变量s来模拟桌子上面的牌
struct queue q1,q2;
struct stack s;
  • 2、初始化队列和栈
#初始化队列q1和q2为空,此时2人手中都还没有牌
q1.head=1;
q1.tail=1;
q2.head=1;
q2.tail=1;
#初始化栈S为空,最开始的时候桌上也没有牌
s.top=0;
  • 接下来需要读入小A和小B手中的牌,分2次读入,每次读入6个数,分别插入q1和q2中。
#先读入6张牌,放入小A手上
for (i=1;i<6;i++)
{
 scanf("%d",&q1.data[q1.tail]); #读入一个数进入队尾
 q1.tail++; #队尾往后挪一位
}
//再读入6张牌,放到小B手中
for (i=1;i<6;i++)
{
scanf("%d",&q2.data[q2.tail]);
q2.tail++;
}

下面就是需要将桌子上面的每一张牌进行枚举看是否与2人的牌一样,进行对比,下面就直接上全部的代码啦~~~

#include<stdio.h>
struct queue
{
	int data [1000];
	int head;
	int tail;
};
struct stack
{
	int data[10];
	int top;
};
int main()
{
	struct queue q1,q2;
	struct stack s;
	int book[10];
	int i,t;
	//初始化队列
	q1.head=1;q1.tail=1;
	q2.head=1;q2.tail=1;
	//初始化栈
	s.top=0;
	//初始化用来标记的数组,用来标记哪些牌已经在桌上
	for(i=1;i<=9;i++)
		book[i]=0;
	//依次向队列插入6个数
	//小A手上的牌
	for(i=1;i<=6;i++)
	{
		scanf("%d",&q1.data[q1.tail]);
		q1.tail++;
	}
	//小B手上的6张牌
	for(i=1;i<=6;i++)
	{
		scanf("%d",&q2.data[q2.tail]);
		q2.tail++;
	}
	while(q1.head<q1.tail&&q2.head<q2.tail)//当队列不为空的时候执行循环
	{
		t=q1.data[q1.head];//小A出一张牌
		//判断小A当前打出的牌是否能赢牌
		if(book[t]==0)//表明桌上没有牌面为t的牌
		{
			//小A此轮没有赢牌
			q1.head++;//小A已经打出一张牌,所以要打出的牌出队
			s.top++;
			s.data[s.top]=t;//再把打出的牌放在桌上,即入栈
			book[t]=1;//标记桌上现在已经有牌面为t的牌
		}
		else
		{
			//小A此轮可以赢牌
			q1.head++;//小A 已经打出一只牌了,所以要把打出的牌出队
			q1.data[q1.tail]=t;//紧接着把打出的牌放到手中牌的末尾
			q1.tail++;
			while(s.data[s.top]!=t)//把桌子可以赢得的牌依次放到手中牌的末尾
			{
				book[s.data[s.top]]==0;//取消标记
				q1.data[q1.tail]=s.data[s.top];//依次放入队尾
				q1.tail++;
				s.top--;//栈中少了一张牌,所以栈顶要减1
			}
			book[s.data[s.top]]==0;
			q1.data[q1.tail]=s.data[s.top];
			q1.tail++;
			s.top--;
	  }
	 if(q1.head==q1.tail) break;//小A手中的牌如果已经打完,游戏结束
			t=q2.data[q2.head];//小B 出一张牌
			//判断小B当前打出的牌是否能够赢牌
			if(book[t]==0)//表明桌上么有牌面为t的牌
			{
				//小B 此轮没有赢牌
				q2.head++;
				s.top++;
				s.data[s.top]=t;
				book[t]=1;//标记桌上现在有牌面为t的牌
			}
			else
			{
			//小B此轮可以赢牌
			q2.head++;
			q2.data[q2.tail]=t;
			q2.tail++;
			while(s.data[s.top]!=t)
			{
				book[s.data[s.top]]=0;
				q2.data[q2.tail]=s.data[s.top];
				q2.tail++;
				s.top--;
			}
			//收回桌上牌面为t的牌
			book[s.data[s.top]]==0;
			q2.data[q2.tail]=s.data[s.top];
			q2.tail++;
			s.top--;
			}
		}
	if(q2.head==q2.tail)
	{
		print("小AWIN\n");
		print("小A当前手中的牌是");
		for(i=q1.head;i<q1.tail-1;i++)
			print("%d",q1.data[i]);
		if(s.top>0)
		{
			print("\n桌上的牌是");
			for(i=1;i<=s.top;i++)
				print("%d",s.data[i]);
		}
		else
			print("\n桌上已经么有牌了");
	}
	else
		{
			print("小B WIN\n");
			print("小B当前手中的牌是");
		    for(i=q2.head;i<q2.tail-1;i++)
			   print("%d",q2.data[i]);
		if(s.top>0)
		{
			print("\n桌上的牌是");
			for(i=1;i<=s.top;i++)
				print("%d",s.data[i]);
		}
		else
			print("\n桌上已经没有牌了");
	}
	getchar();getchar();
		return 0;
}

可以输入以下数据进行验证:
2 4 1 2 5 6
3 1 3 5 6 4
运行结果是:
小BWIN
小B当前手中的牌是 1 6 5 2 3 4 1
桌上的牌是 3 4 5 6 2
大家快去试试吧~~,看看有没有更方便的方法可以解决这个问题,欢迎来交流呀!!!

本文标签: 小猫纸牌技术游戏