星期天A和B在一起玩扑克牌,他们在玩一个古怪的扑克牌游戏——小猫钓鱼。游戏的规则是这样的,将一副扑克牌平均分成两份,每人拿一份。A先拿出手中的第一章牌放在桌上,然后B也从手里拿出一张牌放在桌上,就放在A刚刚出牌的上面,就像这样两个人交替出牌。出牌时,如果某人打出的牌与桌面上某张牌的牌面相同,即可将两张相同的牌和其中夹的牌全部取走,并依次放到自己的牌的末尾。当一个人的牌耗尽时,游戏结束,对手获胜。
假如游戏开始时,A手中有6张牌,顺序为2 4 1 2 5 6,B手中也有6张牌,顺序为3 1 3 5 6 4,最终谁会获胜呢。
先分析一下这游戏有几种操作,A有两种操作,分别是出牌和赢牌。这恰好对应队列的两个操作,出牌就是出队,赢牌就是入队。B的操作也是一样的。而桌子就像是一个栈,每打一张牌到桌子上就相当于入栈,有人赢牌时就相当于出栈。根据之前的规则,我们需要两个队列,一个栈来模拟游戏。
首先创建一个结构体来模拟实现队列:
struct queue
{
int data[1000];
int head;
int tail;
};
上面代码中head用来存储队头,tail用来存储队尾。数组data用来存储队列中的元素,数组data的大小预设为1000,其实应该设置的更大一些,以防数组越界。
再创建一个结构体来实现栈:
struct stack
{
int data[10];
int top;
};
其中top用来存储栈顶,数组data用来存储栈中的元素,大小设置为10,因为牌面数字就只有0~9不同的牌面,所以桌面上最多有9张牌,因此数组的大小设置为10就够了。
接下来需要定义两个队列变量q1和q2。用来模拟A和B手里的牌。定义一个栈变量来模拟桌上的牌。
struct queue q1, q2;
struct stack s;
接下来来初始化一下队列和栈;
// 队列和栈都初始化为空,因为一开始手上和桌上都没有牌
q1.head = 0;
q1.tail = 0;
q2.head = 0;
q2.tail = 0;
s.top = 0;
接下来需要读入A和B手中的初始的牌,分两次读入,每次读入6个数,分别插入q1和q2中。
for (i = 0; i < 6; i++) {
scanf("%d", &q1.data[q1.tail++]);
}
for (i = 0; i < 6; i++) {
scanf("%d", &q2.data[q2.tail++]);
}
现在准备工作已经完毕,游戏正式开始,A先出牌
t = q1.data[q1.head];
A打出一张牌后,先把这个牌存到临时变量里,然后去判断A是否能够赢回桌上的牌。也就是判断桌面上有没有和A打出的牌相同的牌。
flage = 0;
for (i = 1; i <= s.top; i++) {
if (t == s.data[i]) {
flag = 1;
break;
}
}
如果flag为1就表示A可以赢走桌上的牌,需要将赢得的牌依次放入A的手中
if (flage == 1) {
q1.head++;
q1.data[q1.tail] = t;
q1.tail++;
while (s.data[s.top] != t) {
q1.data[q1.tail] = s.data[s.top];
q1.tail++;
s.top--;
}
}
A出牌的所有阶段模拟结束了,B和A出牌是一样的。接下来就判断游戏怎么结束。即两个人中有一个人的牌用完了就游戏结束了。因此需要在模拟两个人出牌的代码外面加一个while循环来判断:
while(q1.head < q1.tail && q2.head < q2.tail) // q1和q2都不为空的时候执行出牌循环
最后一步,输出谁最后赢了游戏,以及游戏结束后获胜者手上的牌和桌上的牌。如果A获胜了,B手上就没有牌了,即q2.head == q2.tail,队列为空。
if (q2.head == q2.tail) {
printf("A WIN\n");
printf("A 手中的牌是:");
for (i = q1.head; i < q1.tail; i++) {
printf(" %d", q1.data[i]);
}
if (s.top > 0) {
printf("桌上的牌是:");
for (i = 0; i <= s.top; i++){
printf(" %d", s.data[i]);
}
} else {
printf("桌上已经没有牌了");
}
}
反之B获胜,现在代码已经实现的差不多了。
当然,代码还有很多的可以优化的地方,完整代码如下:
#include
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 = 0;
q1.tail = 0;
q2.head = 0;
q2.tail = 0;
s.top = 0;
for (i = 1; i <= 9; i++) {
book[i] = 0;
}
for (i = 0; i < 6; i++) {
scanf("%d", &q1.data[q1.tail++]);
}
for (i = 0; i < 6; i++) {
scanf("%d", &q2.data[q2.tail++]);
}
while(q1.head < q1.tail && q2.head < q2.tail) {
t = q1.data[q1.head];
if (book[t] == 0) {
q1.head++;
s.top++;
s.data[s.top] = t;
book[i] = i;
} else {
q1.head++;
q1.data[q1.tail] = t;
q1.tail++;
while (s.data[s.top] != t) {
book[s.data[s.top]] = 0;
q1.data[q.tail] = s.data[s.top];
s.top--;
}
book[s.data[s.top]] = 0;
q1.data[q1.tail] = s.data[s.top];
q1.tail++;
s.top--;
}
t = q2.data[q2.head];
if (book[t] == 0) {
q2.head++;
s.top++;
s.data[s.top] = t;
book[i] = i;
} else {
q2.head++;
q2.data[q2.tail] = t;
q2.tail++;
while (s.data[s.top] != t) {
book[s.data[s.top]] = 0;
q2.data[q.tail] = s.data[s.top];
s.top--;
}
book[s.data[s.top]] = 0;
q2.data[q2.tail] = s.data[s.top];
q2.tail++;
s.top--;
}
}
if (q2.head == q2.tail) {
printf("A WIN\n");
printf("A 手中的牌是:");
for (i = q1.head; i < q1.tail; i++) {
printf(" %d", q1.data[i]);
}
if (s.top > 0) {
printf("桌上的牌是:");
for (i = 0; i <= s.top; i++){
printf(" %d", s.data[i]);
}
} else {
printf("桌上已经没有牌了");
}
} else {
printf("B WIN\n");
printf("B 手中的牌是:");
for (i = q2.head; i < q2.tail; i++) {
printf(" %d", q2.data[i]);
}
if (s.top > 0) {
printf("桌上的牌是:");
for (i = 0; i <= s.top; i++){
printf(" %d", s.data[i]);
}
} else {
printf("桌上已经没有牌了");
}
}
return 0;
}
输入参数
2 4 1 2 5 6
3 1 3 5 6 4
验证模拟即可。