小猫钓鱼算法(队列+栈练习)
星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。
小哼先拿出手中的第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。
当任意一人手中的牌全部出完时,游戏结束,对手获胜。
假如游戏开始时,小哼手中有 6 张牌,顺序为 2 4 1 2 5 6,小哈手中也有 6 张牌,顺序为 3 1 3 5 6 4,最终谁会获胜呢?现在你可以拿出纸牌来试一试。接下来请你写一个程序来自动判断谁将获胜。这里我们做一个约定,小哼和小哈手中牌的牌面只有 1~9。
思路:
每人有两种操作,分别是出牌和赢牌。这恰好对应队列的两个操作,出牌就是出队,赢牌就是入队。而桌子就是一个栈,每打出一张牌放到桌上就相当于入栈。当有人赢牌的时候,依次将牌从桌上 拿走,这就相当于出栈。
赢牌的规则是:如果某人打出的牌与桌上的某张牌相同,即可将两张牌以及中间所夹的牌全部取走。因为牌面为1-9,可以建一个数组初始化为0,当牌面n出现在桌子上后数组【n】=1(类似桶排序)
需要两个队列、一个栈来模拟整个游戏
具体代码实现如下:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
public class 小猫钓鱼 {
public static void main(String[] args) {
Stack<Integer> deskStack = new Stack<>();//桌子上的牌,用栈进行管理
Queue<Integer> playerA = new LinkedList();//用队列管理每个选手的牌
Queue<Integer> playerB = new LinkedList();
int book[] = new int[10];
Scanner scanner = new Scanner(System.in);
//发牌,每人6张
for (int i = 0; i < 6; i++) {
playerA.add(scanner.nextInt());
}
for (int i = 0; i < 6; i++) {
playerB.add(scanner.nextInt());
}
//当两个队列都不为空,表示游戏没有结束
while (!playerA.isEmpty() && !playerB.isEmpty()) {
int ta = playerA.peek();//A出一张牌
//判断A出的牌能不能赢牌
if (book[ta] == 0) {//桌子上没有这张牌
//A不能赢牌
playerA.remove();//打出的牌出队列
deskStack.add(ta);//打出的牌入栈
book[ta] = 1;//标记打出的牌出现在桌子上
} else {//A能赢牌
playerA.remove();//打出的牌出队列
playerA.add(ta);//打出的牌入队列
while (deskStack.lastElement() != ta) {
book[deskStack.lastElement()] = 0;
playerA.add(deskStack.lastElement());
deskStack.pop();
}
}
int tb = playerB.peek();//B出一张牌
//判断B出的牌能不能赢牌
if (book[tb] == 0) {//桌子上没有这张牌
//B不能赢牌
playerB.remove();//打出的牌出队列
deskStack.add(tb);//打出的牌入栈
book[tb] = 1;//标记打出的牌出现在桌子上
} else {//B能赢牌
playerB.remove();//打出的牌出队列
playerB.add(tb);//打出的牌入队列
while (deskStack.lastElement() != tb) {
book[deskStack.lastElement()] = 0;
playerB.add(deskStack.lastElement());
deskStack.pop();
}
}
}
if (playerA.isEmpty()) {
System.out.println("B赢了");
System.out.print("B手中的牌为:");
while (!playerB.isEmpty()) {
System.out.print(playerB.peek() + " ");
playerB.remove();
}
} else {
System.out.println("A赢了");
System.out.print("A手中的牌为:");
while (!playerA.isEmpty()) {
System.out.print(playerA.peek() + " ");
playerA.remove();
}
}
System.out.println("");
System.out.print("桌子上的牌为:");
while (!deskStack.isEmpty()) {
System.out.print(deskStack.lastElement() + " ");
deskStack.pop();
}
}
}
输入手中牌的个数 6 输入A君手中牌的大小 2 4 1 2 5 6 输入B君手中牌的大小 3 1 3 5 6 4 输入完毕开始游戏 A君胜利!A手中的牌是 5 6 2 3 1 4 6 5 桌面上的牌是 2 1 3 4
补充知识: Stack<Integer> stack = new Stack<>(); stack1.peek() 返回栈顶元素,但不在堆栈中删除它。 Stack2.pop() 返回栈顶元素,并在进程中删除它。 总结一下: 当我们只需要取出栈顶的元素进行处理(或者说我们需要先对栈顶的数据进行处理例如比较)然后根据处理的结果进行决定是否要pop(),这种情况下,我们可以先使用peek()方法,取出栈顶的值。 补充总结一下栈中的其他常用的方法: empty( )——如果堆栈是空的,则返回true,当堆栈包含元素时,返回false;
参考:https://blog.csdn.net/Late_whale/article/details/111463791


浙公网安备 33010602011771号