【蓝桥杯】【啊哈!算法】纸牌游戏——小猫钓鱼(队列和栈的应用)

【啊哈!算法】系列文章目录



需求介绍

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

数据输入: 第一行分别为为小哼、小哈手中牌的数目,第二行是小哼手中的牌,第三行是小哈手中的牌,不同牌之间用空格隔开。
数据输出: 第一行是胜利者,如小哼胜,则为“小哼win”;如小哈胜,则为“小哈win”;
      第二行是胜利者手中的牌,中间用空格隔开;
      第三行是桌上的牌,中间用空格隔开。


思路分析

  我们先来分析一下这个游戏有哪几种操作。小哼有两种操作,分别是出牌和赢牌。这恰好对应队列的两个操作,出牌就是出队,赢牌就是入队。小哈的操作和小哼是一样的。而桌子就是一个,每打出一张牌放到桌上就相当于入栈。当有人赢牌的时候,依次将牌从桌上拿走,这就相当于出栈。那如何解决赢牌的问题呢?赢牌的规则是:如果某人打出的牌与桌上的某张牌相同,即可将两张牌以及中间所夹的牌全部取走。那如何知道桌上已经有哪些牌了呢?最简单的方法就是枚举桌上的每一张牌,当然也有更好的办法,就是用一个数组来记录桌上有哪些牌。因为牌面只有 1~9,因此只需开一个大小为 10 的数组来记录当前桌上已经有哪些牌面就可以了。

  OK,小结一下,我们需要两个队列、一个栈来模拟整个游戏。

C语言代码

#include <stdio.h>

struct queue {
   
	int data[1000];
	int head;
	int tail;
};

struct stack {
   
	int data[20];
	int top;
};

int book[20];

void chupai(struct queue *q, struct stack *s) {
   
	int t;
	t = q->data[q->head]; //小哼出一张牌
	q->head++;
	// 判断小哼当前打出的牌是否能赢得桌上的牌
	if(book[t]==0) {
    //表明桌上没有牌面为t的牌
		//小哼此轮没有赢牌
		s->top++;
		s->data[s->top] = t;  //再把打出的牌放到桌上,即入栈
		book[t] = 1;  //标记桌上现在已经有牌面为t的牌
	}
	else {
   
		//小哼此轮可以赢牌
		q->data[q->tail] = t; //因为此轮可以赢牌,所以紧接着把刚才打出的牌又放到手中牌的末尾
		q->tail++;
		while(s->data[s->top]!=t) {
     //把桌上可以赢得的牌(从当前桌面最顶部一张牌开始取,直至取到与打出的牌相同为止)依次放到手中牌的末尾
			book[s->data[s->top]]=0; //取消标记
			q->data[q->tail] = s->data[s->top]; ///依次放入队尾
			q->tail++;
			s->top--;  //栈中少了一张牌,所以栈顶要减1
		}
		
		//收起最后一张一样的牌,并将标志置0 
		book[s->data[s->top]]=0; //取消标记
		q->data[q->tail] = s->data[s->top]; ///依次放入队尾
		q->tail++;
		s->top--;  //栈中少了一张牌,所以栈顶要减
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_43964993

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值