蓝桥每日打卡--拉马车

#蓝桥#JAVA#拉马车

题目描述

小的时候,你玩过纸牌游戏吗?

有一种叫做"拉马车"的游戏,规则很简单,却很吸引小朋友。

其规则简述如下:

假设参加游戏的小朋友是A和B,游戏开始的时候,他们得到的随机的纸牌序列如下:

A方:[K,8,X,K,A,2,A,9,5,A]

B方:[2,7,K,5,J,5,Q,6,K,4]

其中的X表示 "10",我们忽略了纸牌的花色。

从A方开始,A、B双方轮流出牌。

当轮到某一方出牌时,他从自己的纸牌队列的头部拿走一张,放到桌上,并且压在最上面一张纸牌上(如果有的话)。

此例中,游戏过程:

A出 K,B出 2,A出8,B出7,A出X,此时桌上的序列为:

K,2,8,7,X

当轮到B出牌时,他的牌K与桌上的纸牌序列中的K相同,则把包括K在内的以及两个K之间的纸牌都赢回来,放入自己牌的队尾。注意:为了操作方便,放入牌的顺序是与桌上的顺序相反的。

此时,A、B双方的手里牌为:

A方:[K,A,2,A,9,5,A]

B方:[5,J,5,Q,6,K,4,K,X,7,8,2,K]

赢牌的一方继续出牌。也就是B接着出5,A出K,B出J,A出A,B出5,又赢牌了。此时桌上的序列为:

5,K,J,A,5

此时双方手里牌:

A方:[2,A,9,5,A]

B方:[Q,6,K,4,K,X,7,8,2,K,5,A,J,K,5]

注意:更多的时候赢牌的一方并不能把桌上的牌都赢走,而是拿走相同牌点及其中间的部分。但无论如何,都是赢牌的一方继续出牌,有的时候刚一出牌又赢了,也是允许的。

当某一方出掉手里最后一张牌,但无法从桌面上赢取牌时,游戏立即结束。

对于本例的初始手牌情况下,最后A会输掉,而B最后的手里牌为:

9K2A62KAX58K57KJ5

本题的任务就是已知双方初始牌序,计算游戏结束时,赢的一方手里的牌序。当游戏无法结束时,输出 -1。

解题思路:

  • 数据结构选择:使用 StringBuilder 来存储玩家的手牌和桌上的牌,因为 StringBuilder 可以高效地进行字符串的拼接、删除和反转操作,符合游戏中添加牌、移除牌和反转牌顺序的需求。
  • 循环控制:通过一个 while 循环来模拟游戏的进行,只要两个玩家的手牌都不为空,游戏就继续进行。
  • 出牌逻辑:使用一个布尔变量 flag 来控制轮到哪个玩家出牌,每次出牌后切换 flag 的值。
  • 收牌逻辑:当出牌时发现桌上已经存在相同的牌,调用 check 方法进行收牌操作。

具体步骤

1. 输入处理
  • 使用 Scanner 类从标准输入读取两个字符串,分别存储到 StringBuilder 对象 A 和 B 中,作为两个玩家的初始手牌。
  • 创建一个空的 StringBuilder 对象 desk 用于存储桌上的牌。
2. 初始化变量
  • 声明一个整数变量 index 用于存储在桌上的牌中查找相同牌的索引位置。
  • 声明一个布尔变量 flag 并初始化为 true,表示游戏开始时由玩家 A 先出牌。
3. 游戏循环
  • 使用 while 循环,条件为 A.length() > 0 && B.length() > 0,即只要两个玩家的手牌都不为空,游戏就继续进行。
  • 在每次循环中,根据 flag 的值判断轮到哪个玩家出牌:
    • 玩家 A 出牌
      • 检查玩家 A 手牌的第一张牌是否存在于桌上的牌中,使用 desk.indexOf(String.valueOf(A.charAt(0))) 方法进行查找。
      • 如果不存在(返回值为 -1),将该牌添加到桌上的牌末尾,并从玩家 A 的手牌中移除该牌,然后将 flag 置为 false,表示下一轮轮到玩家 B 出牌。
      • 如果存在,调用 check 方法进行收牌操作。
    • 玩家 B 出牌
      • 与玩家 A 出牌逻辑类似,检查玩家 B 手牌的第一张牌是否存在于桌上的牌中。
      • 如果不存在,将该牌添加到桌上的牌末尾,并从玩家 B 的手牌中移除该牌,然后将 flag 置为 true,表示下一轮轮到玩家 A 出牌。
      • 如果存在,调用 check 方法进行收牌操作。
4. 收牌操作
  • 定义 check 方法,该方法接受三个参数:当前出牌玩家的手牌 hand、桌上的牌 desk 和相同牌在桌上的索引位置 index
  • 将当前出牌玩家手牌的第一张牌添加到桌上的牌末尾,并从手牌中移除该牌。
  • 截取桌上从 index 位置开始到末尾的所有牌,存储到一个新的 StringBuilder 对象 C 中。
  • 将 C 中的牌顺序反转,然后添加到当前出牌玩家的手牌末尾。
  • 从桌上的牌中删除从 index 位置开始到末尾的所有牌。
5. 游戏结束判断
  • 当 while 循环结束时,说明其中一个玩家的手牌为空,此时判断哪个玩家的手牌为空,输出另一个玩家的手牌作为获胜者的手牌。

其中需要注意的方法

desk.indexOf() 方法在 desk 中查找玩家 A 手牌的第一张牌(即 A.charAt(0))第一次出现的索引位置;String.valueOf() 方法将字符转换为字符串,因为 indexOf() 方法接受的参数是字符串。如果找到该字符,则返回其索引;如果未找到,则返回 -1;将玩家 A 手牌的第一张牌添加到 desk 中,使用 append() 方法;然后从玩家 A 的手牌中删除这张牌,使用 delete(0, 1) 方法;使用 substring(index) 方法截取 desk 中从 index 位置开始到末尾的所有字符,并添加到 C 中。

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        StringBuilder A = new StringBuilder(scan.next());//手牌
        StringBuilder B = new StringBuilder(scan.next());
        StringBuilder desk = new StringBuilder();//桌上牌
        int index;//检索桌上牌的标号
        boolean flag = true;//判断该谁出牌
        while(A.length() > 0 && B.length() > 0){//当A和B还有牌,就进行循环
          if(flag){//A出牌
            index = desk.indexOf(String.valueOf(A.charAt(0)));
            //判断A第一张牌在桌上牌是否出现,出现赋值给index,没有则输出-1
            if(index == -1){//桌上没有A第一张牌
              desk.append(A.charAt(0));//将牌放桌上
              A.delete(0,1);//把第一张牌从A手中删除
              flag = false;//该B出牌
            }else{//桌上有这张牌,开始收牌
              check(A,desk,index);
            }
          }else{//B出牌
            index = desk.indexOf(String.valueOf(B.charAt(0)));
            if(index == -1){
              desk.append(B.charAt(0));
              B.delete(0,1);
              flag = true;
            }else{
              check(B,desk,index);
            }
          }
        }
        if(A.length() == 0){
          System.out.println(B);
        }else{
          System.out.println(A);
        }
        scan.close();
    }
    static void check(StringBuilder hand,StringBuilder desk,int index){
      StringBuilder C = new StringBuilder();//要收回的牌
      desk.append(hand.charAt(0));//将牌添加到桌面
      hand.delete(0,1);//删除手上的牌
      C.append(desk.substring(index));//从index开始到最后收牌
      hand.append(C.reverse());//将牌翻转放入手中
      desk.delete(index,desk.length());//桌上的牌删除部分
    }
}

你可能感兴趣的:(java,算法,开发语言,蓝桥杯)