#蓝桥#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
方法进行收牌操作。Scanner
类从标准输入读取两个字符串,分别存储到 StringBuilder
对象 A
和 B
中,作为两个玩家的初始手牌。StringBuilder
对象 desk
用于存储桌上的牌。index
用于存储在桌上的牌中查找相同牌的索引位置。flag
并初始化为 true
,表示游戏开始时由玩家 A 先出牌。while
循环,条件为 A.length() > 0 && B.length() > 0
,即只要两个玩家的手牌都不为空,游戏就继续进行。flag
的值判断轮到哪个玩家出牌:
desk.indexOf(String.valueOf(A.charAt(0)))
方法进行查找。flag
置为 false
,表示下一轮轮到玩家 B 出牌。check
方法进行收牌操作。flag
置为 true
,表示下一轮轮到玩家 A 出牌。check
方法进行收牌操作。check
方法,该方法接受三个参数:当前出牌玩家的手牌 hand
、桌上的牌 desk
和相同牌在桌上的索引位置 index
。index
位置开始到末尾的所有牌,存储到一个新的 StringBuilder
对象 C
中。C
中的牌顺序反转,然后添加到当前出牌玩家的手牌末尾。index
位置开始到末尾的所有牌。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());//桌上的牌删除部分
}
}