今天看到《啊哈算法》小猫钓鱼这个题感觉挺有意思的,用Java写了一下(思路一样,写了两种,一个自定义类,另一个是直接导入的队列和栈,建议对队列和栈不熟悉的同学先看看自定义的,这也是Java比之C的一个弊端,现成的东西太多,反而学起来不好理解)
题目要求:
两人比赛,A,B,每人最开始分得6张手牌,手牌大小为从1到9
A先出牌,B后出牌,若出牌在桌面上存在,在出牌人获得两张相同牌中间的所有牌(包括两张相同牌),放入出牌人手中。
最后谁手中无牌判为负
思路:
每人有两种操作,分别是出牌和赢牌。这恰好对应队列的两个操作,出牌就是出队,赢牌就是入队。而桌子就是一个栈,每打出一张牌放到桌上就相当于入栈。当有人赢牌的时候,依次将牌从桌上 拿走,这就相当于出栈。
赢牌的规则是:如果某人打出的牌与桌上的某张牌相同,即可将两张牌以及中间所夹的牌全部取走。因为牌面为1-9,可以建一个数组初始化为0,当牌面n出现在桌子上后数组【n】=1(类似桶排序)
需要两个队列、一个栈来模拟整个游戏
代码_自定义:
import java.util.Scanner;
class queue{
int[] data=new int[1000];
int head,tail;
}
class stack{
int[] data=new int[10];
int top;
}
public class 小猫钓鱼 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
queue ha=new queue();
queue heng=new queue();
stack table=new stack();
ha.head=0;ha.tail=0;
heng.head=0;heng.tail=0;
table.top=0;
int tmp;
int[] book=new int[10];//记录牌的重复,类似桶排序
for (int i = 0; i < book.length; i++) {
book[i]=0;
}
for (int i = 0; i < 6; i++) {
ha.data[ha.tail]=input.nextInt();
ha.tail++;
}
for (int i = 0; i < 6; i++) {
heng.data[heng.tail]=input.nextInt();
heng.tail++;
}
while (ha.head<ha.tail&&heng.head<heng.tail) {
tmp = heng.data[heng.head];//小哼打出第一张牌放入临时变量
if (book[tmp] == 0) {//桌子上没有等于t的牌,小哼没能赢牌
heng.head++;//去掉第一张牌
table.data[++table.top] = tmp;//放到桌子上(入栈)
book[tmp] = 1;
} else {
heng.head++;
heng.data[heng.tail] = tmp;
heng.tail++;
while (table.data[table.top] != tmp) {//一直拿牌到与打出的牌相等的那个
book[table.data[table.top]] = 0;
heng.data[heng.tail] = table.data[table.top];
heng.tail++;
table.top--;
}
}
tmp = ha.data[ha.head];//小哈打出第一张牌放入临时变量
if (book[tmp] == 0) {//桌子上没有等于t的牌,小哼没能赢牌
ha.head++;//去掉第一张牌
table.data[++table.top] = tmp;//放到桌子上(入栈)
book[tmp] = 1;
} else {
ha.head++;
ha.data[ha.tail] = tmp;
ha.tail++;
while (table.data[table.top] != tmp) {//一直拿牌到与打出的牌相等的那个
book[table.data[table.top]] = 0;
ha.data[ha.tail] = table.data[table.top];
ha.tail++;
table.top--;
}
}
}
if (ha.head==ha.tail){
System.out.println("小哈输了,小哼的牌为:");
for (int i = heng.head; i < heng.tail; i++) {
System.out.print(heng.data[i]+" ");
}
System.out.println();
System.out.println("桌子上的牌为:");
if (table.top>0) {
for (int i=1;i<=table.top;i++)
System.out.print(table.data[i] + " ");
}else
System.out.println("桌上没牌了");
}else {
System.out.println("小哈赢了");
}
}
}
代码_调用:
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();
}
}
}
以上