[特殊字符] 2025蓝桥杯备赛Day3——B2112 石头剪子布

🔍 2025蓝桥杯备赛Day3——B2112 石头剪子布

🚀 题目速览

题目难度:⭐️ 适合编程新手掌握条件分支与字典应用

考察重点:逻辑判断、数据结构应用、多组数据处理

Day3——B2112 石头剪子布

题目描述

石头剪子布,是一种猜拳游戏。起源于中国,然后传到日本、朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代逐渐风靡世界。简单明了的规则,使得石头剪子布没有任何规则漏洞可钻,单次玩法比拼运气,多回合玩法比拼心理博弈,使得石头剪子布这个古老的游戏同时用于“意外”与“技术”两种特性,深受世界人民喜爱。

游戏规则:石头打剪刀,布包石头,剪刀剪布。

现在,需要你写一个程序来判断石头剪子布游戏的结果。

输入格式

第一行是一个整数 N N N,表示一共进行了 N N N 次游戏。 1 ≤ N ≤ 100 1 \le N \le 100 1N100

接下来 N N N 行的每一行包括两个字符串,表示游戏参与者 Player1,Player2 的选择(石头、剪子或者是布):
S1,S2

字符串之间以空格隔开 S1 S2 只可能取值在 Rock,Scissors,Paper (大小写敏感)中。

输出格式

输出包括 N N N 行,每一行对应一个胜利者(Player1 或者 Player2),或者游戏出现平局,则输出 Tie

输入输出样例 #1

输入 #1

3
Rock Scissors
Paper Paper
Rock Paper

输出 #1

Player1
Tie
Player2

🔥 解法一:字典映射法(扩展性优)

🛠️ 实现思路

核心技巧:建立胜负关系哈希表实现快速查询

算法优势:时间复杂度O(1)单次判断,规则变更时只需修改字典

#include <iostream>
#include <unordered_map>
using namespace std;

int main() {
    int N;
    cin >> N;
    unordered_map<string, string> win_rules = {
        {"Rock", "Scissors"},  // Rock击败Scissors
        {"Scissors", "Paper"}, // Scissors击败Paper
        {"Paper", "Rock"}      // Paper击败Rock
    };
    while (N--) {
        string s1, s2;
        cin >> s1 >> s2;
        if (s1 == s2) {
            cout << "Tie" << endl;
        } else {
            cout << (s2 == win_rules[s1] ? "Player1" : "Player2") << endl;
        }
    }
    return 0;
}
关键知识点
  1. 哈希表快速查询:通过键值对直接获取胜负关系
  2. 三元表达式优化:简化条件分支写法
  3. 规则集中管理:所有胜负关系存储于单一数据结构

🔥 解法二:条件分支法(代码量少)

🛠️ 实现思路

核心技巧:通过首字母简化判断逻辑

代码特点:直接比较首字母,减少字符串操作开销

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    while (n--) {
        string a, b;
        cin >> a >> b;
        
        if (a[0] == b[0]) {
            cout << "Tie\n";
        } 
        else if (a[0] == 'R') {
            cout << (b[0] == 'P' ? "Player2\n" : "Player1\n");
        } 
        else if (a[0] == 'S') {
            cout << (b[0] == 'R' ? "Player2\n" : "Player1\n");
        } 
        else if (a[0] == 'P') {
            cout << (b[0] == 'S' ? "Player2\n" : "Player1\n");
        }
    }
    return 0;
}

💡 关键改进点

  1. 语法修正:统一使用单引号进行字符比较
  2. 结构优化:使用三元表达式替代嵌套if-else
  3. 输入方式while(n--)循环更符合C++习惯

📚 知识点总结

一、哈希表(unordered_map)

  1. 底层原理 基于哈希函数将键映射到存储桶,通过链表处理冲突。 特性

    • 平均查询时间复杂度O(1)
    • 键唯一且无序存储
  2. 胜负规则定义

    unordered_map<string, string> win_rules = {
        {"Rock", "Scissors"},  // 键:玩家1选择,值:击败的对象
        {"Scissors", "Paper"},
        {"Paper", "Rock"}
    };
    
    • 查询逻辑:若s2 == win_rules[s1],说明玩家1的选择击败了玩家2。
  3. 扩展应用

    // 处理多对多关系(如新增手势)
    unordered_map<string, set<string>> win_rules = {
        {"Rock", {"Scissors", "Lizard"}}
    };
    

二、三元条件运算符

  1. 语法结构 条件 ? 表达式1 : 表达式2

    • 示例:

      cout << (s2 == win_rules[s1] ? "Player1" : "Player2");
      
  2. 关键细节

    • 表达式1和表达式2的类型必须一致
    • 优先级低于比较运算符,需用括号包裹条件部分

三、首字母比较法

  1. 实现原理 利用字符串首字母快速判断类型:

    if (a[0] == 'R') {  // 'R'代表Rock
        // 判断逻辑...
    }
    
  2. 注意事项

    • 仅适用于输入严格符合规范的情况(如Rock而非rock
    • 新增手势需修改所有分支(如Lizard需判断'L'

四、循环与输入优化

  1. 循环结构选择

    while (n--) { ... }  // 比for循环更简洁,减少变量占用
    
  2. 输入批量读取

    vector<pair<string, string>> records(N);
    for (auto& p : records) cin >> p.first >> p.second;
    

📊 双解法对比分析

维度字典映射法条件分支法
时间复杂度O(1) 每次查询O(1)
扩展性高(仅修改字典)低(需修改分支逻辑)
可读性★★★★★(规则可视化)★★★☆☆(需推导逻辑)
内存占用约30字节(哈希表存储)无额外存储
抗错能力自动处理所有合法输入依赖输入首字母正确性

🚨 常见错误警示

  1. 首字母陷阱
// 错误写法:双引号表示字符串
if (b[0] == "R") → if (b[0] == 'R') // 正确
  1. 魔法值风险
// 建议添加注释说明字符含义
else if (a[0] == 'R') // R代表Rock

🌟 举一反三

变种题1:扩展手势类型

// 增加蜥蜴和史波克
unordered_map<string, set<string>> win_rules = {
    {"Rock", {"Scissors", "Lizard"}},
    {"Scissors", {"Paper", "Lizard"}},
    {"Paper", {"Rock", "Spock"}},
    // 其他规则...
};

变种题2:三局两胜制

int p1_score = 0, p2_score = 0;
// 每局判断逻辑...
cout << (p1_score > p2_score ? "Player1" : "Player2");

🛠️ 实战技巧

  1. 输入校验增强
// 验证输入合法性
if (a != "Rock" && a != "Scissors" && a != "Paper") {
    cout << "Invalid input!";
    continue;
}
  1. 性能优化技巧
// 预先读取所有输入
vector<pair<string, string>> records(N);
for (auto& [a, b] : records) cin >> a >> b; 

蓝桥杯考场策略

  • 规则固定且简单 → 优先选择解法二(编码速度快)
  • 题目存在扩展可能 → 必选解法一(易维护性优)
  • 遇到非法输入处理 → 建议添加校验代码(即使题目未要求)

👉 思考题:若改为玩家2先出拳,如何修改判断逻辑?欢迎在评论区分享你的解法!

(答案提示:交换s1s2的角色,或修改字典键值对方向。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值