当前位置: 首页 > article >正文

【蓝桥杯】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 的手牌。

代码实现

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

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

http://www.kler.cn/a/514597.html

相关文章:

  • c++常见设计模式之装饰器模式
  • SSM开发(二) MyBatis简介
  • 【Mac】Python相关知识经验
  • 计算机网络 (52)秘钥分配
  • Python----Python高级(正则表达式:语法规则,re库)
  • < OS 有关 > 阿里云:轻量应用服务器 的使用 安装 Tailscale 后DNS 出错, 修复并替换 apt 数据源
  • SpringBoot项目中的异常处理
  • RV1126+FFMPEG推流项目源码
  • 浅谈微积分与e^x理解
  • 【机器学习】深入无监督学习分裂型层次聚类的原理、算法结构与数学基础全方位解读,深度揭示其如何在数据空间中构建层次化聚类结构
  • ”彩色的验证码,使用pytesseract识别出来的验证码内容一直是空“的解决办法
  • 2025 年了,你的科研工具箱更新了哪些新工具?
  • 账号IP属地:依据手机号还是网络环境?
  • DeepSeek系列
  • 顺序表和链表(详解)
  • KNN算法原理(深入浅出)
  • nvm版本安装
  • IP协议特性
  • 澎峰科技计算软件栈与沐曦GPU完成适配和互认证
  • 2000-2010年各省第三产业就业人数数据
  • 【单层神经网络】快速入门AI系列
  • 超大型集团合并报表数智管理转型
  • C语言基础------练习1
  • 相机内参的作用原理
  • doris:Stream Load
  • 登录认证(4):令牌技术:JWT令牌