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