小猫钓鱼——(c++用栈和队列实现)

参考书:啊哈算法
题目:星期天小哼和小哈约在一块玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓鱼”(类似小时候玩的丁沟钓鱼)。游戏规则:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的第一张扑克牌放在桌子上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即可将两张相同的牌及其中间所夹得牌全部取走,并依次放到自己自己手中牌的末尾。当人以一人手中的牌全部出完时,游戏结束,对手获胜。

应用知识:用结构体定义栈和队列

题目分析:小哼和小哈手中的牌用两个队列存放,队列用head存储队头,tail存储队尾;出牌就是出队,head++‘’赢牌就是入队,tail++。桌子上的牌用一个栈存放,用top存放栈顶,其中一个人出牌,top++,其中一个人赢牌,top–。有人赢牌的话,依次将桌上的牌拿走。

栈与队列:此题所用的栈顶用top表示,从下标1开始存放数据,top表示栈顶,但top这个下标不存放数据,栈内有效的总数据个数为top-1;类似的,队列的队头和队尾分别用head和tail表示,队头head从1开,队尾tail这个下标也不存放数据,队列内有效的总数据个数为tail - head。

内容须知:类似桶排序,定义一个book数组,全部为零。若桌上有一张牌t,令book[t]=1;

解题思路:
1.定义队列和栈的结构体,定义两个队列q1和q2,一个栈s,初始化队列和栈。
2.把小哼和小哈的牌读入队列内。
3.在两个队列队头都不等于队尾的情况下依次遍历,知道有一方队头等于队尾,游戏结束。
4.小哼先出牌,判断桌面上是否有这张牌(用book数组)。
5.若没有,则把这张牌放到桌面上。
6.若有,则把这张牌放到队尾,然后把两个相同牌中间的牌也依次放到队尾。
7.小哈出牌,类似小哼出牌,和上述步骤5和步骤6一样。

8.判断队头和队尾是否相等,然后根据需求输出想要的。

代码如下:

//方法一:自己定义栈和队列 
#include<iostream>
using namespace std;
struct queue 
{
	int head;
	int tail;
	int data[1000];
};
struct stack
{
	int data[1000];
	int top;
};
int main()
{
	queue q1,q2;//两个人手中的牌存放在队列中
	stack s;
	int i,t,book[10];
	q1.head=q1.tail=1;//队列初始化
    q2.head=q2.tail=1;//队列下标从1开始 
	s.top=1; //栈初始化,下标从1开始
	for(i=1;i<10;i++) 
	    book[i]=0;//初始化用来标记的数组,用来标记那些数已经在桌子上 
	for(i=1;i<=6;i++)
	{
		cin>>q1.data[q1.tail];
		q1.tail++;
	}//小哼q1手上的牌
	for(i=1;i<=6;i++)
	{
		cin>>q2.data[q2.tail];
		q2.tail++;
	}//小哈q2手上的牌 
	while(q1.head<q1.tail && q2.head<q2.tail)
	{
		t=q1.data[q1.head];//小哼q1先出牌;
		if(book[t] == 0)//表示桌面上没有t这张牌 
		{
			q1.head++; 
			s.data[s.top]=t; 
			s.top++;
			book[t]=1;//标记桌子上已有t这张牌 
		}
		else//表示桌面上有t这张牌 
		{
			q1.head++;
			q1.data[q1.tail]=t;//把打的牌放到队尾 
			q1.tail++;
			while((s.data[--s.top]) !=t )//s.top-1才是栈顶的下标 
			{ 
				book[s.data[s.top]]=0;//取消标记 
				q1.data[q1.tail]=s.data[s.top];
				q1.tail++;
			}
			//注意此时下标s.top指的是当前栈顶下标 
			//收回桌面上为t的牌 
			book[s.data[s.top]]=0;
			q1.data[q1.tail]=s.data[s.top];
			q1.tail++;
		}
		if(q1.head == q1.tail) break;
		
		t=q2.data[q2.head];
		if(book[t] == 0)//桌上没有牌t 
		{
			q2.head++;
			s.data[s.top]=t;
			s.top++;
			book[t]=1;
		}
		else//桌上有牌t 
		{
			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指的是当前栈顶下标
			book[s.data[s.top]]=0;
			q2.data[q2.tail]=s.data[s.top];
			q2.tail++;
		}
	} 
	if(q2.head == q2.tail)
	{
		cout<<"小哼 win"<<endl;
		cout<<"小哼当前手中的牌是";
		for(i=q1.head; i<q1.tail; i++)
		    cout<<" "<<q1.data[i];
		cout<<endl;
		if(s.top>1) //桌子上有牌 
		{
			cout<<"此时桌子上的牌为:";
			for(i=1;i<s.top;i++)
			    cout<<" "<<s.data[i];
			cout<<endl;
		} 
		else 
		    cout<<"桌子上已经没有牌了"<<endl;
	} 
	else
	{
		cout<<"小哈 win"<<endl;
		cout<<"小哈当前手中的牌是";
		for(i=q2.head ; i<q2.tail ; i++)
		    cout<<" "<<q2.data[i];
		if(s.top>1)
		{
			cout<<"此时桌子上的牌为:";
			for(i=1;i<s.top;i++)
			    cout<<" "<<s.data[i];
			cout<<endl;
		}
		else 
		    cout<<"桌子上已经没有牌了"<<endl;
	}
	return 0;
}

测试如下:

发布了11 篇原创文章 · 获赞 5 · 访问量 328

猜你喜欢

转载自blog.csdn.net/weixin_44820625/article/details/95723201