【蓝桥杯】43691.拉马车

题目描述

小的时候,你玩过纸牌游戏吗?有一种叫做"拉马车"的游戏,规则很简单,却很吸引小朋友。

其规则简述如下:

假设参加游戏的小朋友是 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,此时桌上的序列为:K287X。

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

此时,𝐴、𝐵 双方的手里牌为:

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,4]

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

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

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

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

9K2462KAX58K57KJ5

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

输入描述

输入为 2 行,2个串,分别表示 A、B 双方初始手里的牌序列。我们约定,输

入的串的长度不超过 30。

输出描述

输出为 1行,1 个串,表示 A 先出牌,最后赢的一方手里的牌序。

输入输出样例

示例

输入

96J5A898QA

6278A7Q973

输出

2J9A7QA6Q6889977

问题分析

该问题分为内外两层循环:

外层循环:不断判断出牌一方出牌后的手牌数量,若为0,则判定另一方胜利,打印另一方的手牌顺序,退出循环,游戏结束;如果遇到无法终止的情况,可以设置一个较大的循环次数,循环次数满足之后退出外层循环,游戏结束。

内层循环:不断判断出牌一方的手牌中第一张是否在桌牌上已有相同点数的牌,如果有,则为赢牌,找到桌牌上相同点数的牌的位置,将从该位置一直到末尾的牌加入赢家的手牌,并将第一张手牌从当前位置移入队列末尾;如果桌牌上没有相同点数的牌,则从手牌中去除该牌并添加到桌牌的末尾。

算法步骤

1.数据初始化:

首先将输入的玩家 A 和玩家 B 的手牌字符串转换为列表 hand_a 和 hand_b。然后创建一个空列表 desktop 用于存储出到桌面上的牌。

2.出牌逻辑函数 play(hand):

该函数接收某个玩家的手牌列表 hand 作为参数。然后检查该名玩家要出的第一张手牌 hand[0] 是否在桌面上:

如果要出的第一张手牌在桌面上,通过 index 方法找到该牌在桌面上的位置 ind。

出牌准备:存储要出的牌 put_card,并从手牌中删除这张牌。

出牌:将要出的牌添加到桌面上。

赢取桌面上从最后一张到 ind 位置(不包括 ind)的牌,并将其逆序添加到玩家手牌中,同时将 put_card 也添加到手牌中。

更新桌面上的牌,去掉被赢取的部分。

赢牌的玩家继续出牌,调用 play(hand) 函数自身。

如果要出的第一张手牌不在桌面上,则将其添加到桌面上,并从手牌中删除这张牌。

3.主游戏循环:

玩家 A 先出牌,调用 play(hand_a)。玩家 A 出牌后,检查玩家 A 的手牌是否为空,若为空则玩家 B 获胜,打印玩家 B 的手牌。

玩家 B 接着出牌,调用 play(hand_b)。玩家 B 出牌后,检查玩家 B 的手牌是否为空,若为空则玩家 A 获胜,打印玩家 A 的手牌。

代码实现

感谢 @徐金亚 老师提供的代码

python 复制代码
import os
import sys

# 将输入的字符串转换为列表,得到玩家 A 手中的牌列表
hand_a = list(input())            
# 将输入的字符串转换为列表,得到玩家 B 手中的牌列表
hand_b = list(input())            
# 出到桌面上的牌列表,初始为空
desktop = []                    

def play(hand):                 
    global desktop
    # 如果当前选手要出的牌 hand[0] 与桌面上的某张牌相同
    if hand[0] in desktop:                  
        # 找到桌面上这张牌的位置
        ind = desktop.index(hand[0])        
        # 存储当前玩家要出的牌
        put_card = hand[0]
        # 当前玩家将手上的第 1 张牌拿出来
        del hand[0:1]                       
        # 将拿出来的牌放到桌面上
        desktop.append(put_card)            
        # 将赢取的牌逆序放到手上,赢取的牌包括桌面上的牌从最后一张到 ind 位置的牌,以及刚刚出的那张牌
        hand.extend(desktop[:ind:-1] + [put_card])    
        # 桌面上的牌更新,即被赢取的部分被去掉
        desktop = desktop[:ind]                     
        # 接着出牌
        play(hand)                                  
    else:
        # 若当前玩家出的牌不在桌面上,将其添加到桌面上
        desktop.append(hand[0])
        # 将手上的第 1 张牌拿出来
        del hand[0:1]


while True:
    # 玩家 A 出牌
    play(hand_a)
    # 如果玩家 A 手中无牌,则玩家 B 获胜,打印玩家 B 手中的牌
    if len(hand_a) == 0:
        print(''.join(hand_b))
        break
    # 玩家 B 出牌
    play(hand_b)
    # 如果玩家 B 手中无牌,则玩家 A 获胜,打印玩家 A 手中的牌
    if len(hand_b) == 0:
        print(''.join(hand_a))
        break
相关推荐
冰万森42 分钟前
【图像处理】——掩码
python·opencv·计算机视觉
Tester_孙大壮42 分钟前
第4章:Python TDD消除重复与降低依赖实践
开发语言·驱动开发·python
wjcroom1 小时前
会议签到系统的架构和实现
python·websocket·flask·会议签到·axum
数据小小爬虫2 小时前
如何使用Python爬虫获取微店商品详情:代码示例与实践指南
开发语言·爬虫·python
chengxuyuan666663 小时前
python基础语句整理
java·windows·python
菜还不练就废了4 小时前
蓝桥杯算法日常|c\c++常用竞赛函数总结备用
c++·算法·蓝桥杯
我想学LINUX5 小时前
【2024年华为OD机试】(C/D卷,200分)- 5G网络建设 (JavaScript&Java & Python&C/C++)
java·c语言·javascript·网络·python·5g·华为od
chengxuyuan666665 小时前
JAVA基础语句整理
java·开发语言·python