题解:学而思编程 划拳

【题目来源】

学而思编程:划拳

【题目描述】

小王和小明在吃饭的时候玩起了划拳游戏。

游戏规则是,每一轮两个人同时说出一个数(只能是 \(5,10,15,20\) 中的一个),若两人说出的数一样,则两人均不计分,否则说出数字更大的人获得两人说出的数差值这么多的分数。

但有一个例外,如果一个人说的 \(20\),但另一个说的是 \(5\)\(10\),则说 \(20\) 的这个人不得分,另一个人得 \(10\) 分。

游戏共进行 \(k\) 轮,求最后两人各自得分。

【输入】

第一行一个整数 \(k\),表示游戏进行的轮数。

接下来 \(k\) 行,每行两个整数分别表示这一轮小王和小明说的数。

【输入】

第一行一个整数 \(k\),表示游戏进行的轮数。

接下来 \(k\) 行,每行两个整数分别表示这一轮小王和小明说的数。

【输出】

一行输出两个整数以空格分开。

分别为小王和小明的得分。

【输入样例】

2
10 15
20 10

【输出样例】

0 15

【核心思想】

  1. 问题分析:给定 \(k\) 轮划拳数据,每轮两人各出 \(x, y \in \{5, 10, 15, 20\}\)。计分规则分两层:特殊规则(\(20\)\(5/10\) 时出 \(20\) 者不得分,对方得 \(10\) 分)优先于一般规则(数字大者得差值分,相同则不计分)。这是一个规则优先级模拟问题,关键在于特殊规则与一般规则的判定顺序。

  2. 算法选择

    • 优先级分支:先判定特殊规则(\(20\)\(5/10\)),再判定一般规则(比大小),确保特殊规则优先覆盖
    • 逐轮模拟:对每轮输入直接计算得分,无需存储历史数据
  3. 关键步骤

    • 初始化\(a = 0\)(小王得分),\(b = 0\)(小明得分)
    • 逐轮处理(循环 \(k\) 次):
      • 读取 \(x\)(小王出的数)、\(y\)(小明出的数)
      • 特殊规则判定(优先检查):
        • \(x = 20\)\((y = 5\)\(y = 10)\)\(b \leftarrow b + 10\)(小王出 \(20\) 但对方出 \(5/10\),小王不得分,小明得 \(10\) 分)
        • 否则若 \(y = 20\)\((x = 5\)\(x = 10)\)\(a \leftarrow a + 10\)(小明出 \(20\) 但小王出 \(5/10\),小明不得分,小王得 \(10\) 分)
      • 一般规则判定(特殊规则不满足时):
        • \(x > y\)\(a \leftarrow a + (x - y)\)
        • 否则(此时 \(x \le y\),由题意 \(x \neq y\) 已排除相等):\(b \leftarrow b + (y - x)\)
    • 输出结果:输出 \(a\)\(b\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(k)\),每轮 \(O(1)\) 判定,共 \(k\)
    • 空间复杂度:\(O(1)\),仅使用 \(a\)\(b\) 两个累加器
  5. 规则优先级模拟的核心思想

    • 特殊优先原则:特殊规则(\(20\)\(5/10\))必须优先于一般规则判定。若先判定一般规则,\(20 > 10\) 会使出 \(20\) 者得 \(10\) 分,与特殊规则矛盾。使用 if-else if 结构确保互斥执行
    • 对称处理:特殊规则对双方对称,分别检查 \(x=20\) 对方为 \(5/10\)\(y=20\) 对方为 \(5/10\) 两种情况
    • 一般规则简化:特殊规则排除后,一般规则只需比较 \(x\)\(y\) 大小,差值即为得分。相等时自然不得分(差值为 \(0\)),无需额外判断
    • 在线累加:边读入边计算,无需存储每轮结果,节省空间
    • 适用于游戏规则模拟、多优先级条件判定类问题

【算法标签】

模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int a, b, k;

int main()
{
    cin >> k;
    for (int i = 1; i <= k; i++)
    {
        int x, y;
        cin >> x >> y;
        // 特殊规则:当一方为20,另一方为5或10时
        if (x == 20 && (y == 5 || y == 10))
        {
            b += 10;  // 玩家b获得10分
        }
        else if (y == 20 && (x == 5 || x == 10))
        {
            a += 10;  // 玩家a获得10分
        }
        else
        {
            // 一般规则:分数高的一方获得差值分数
            if (x > y)
            {
                a += x - y;  // 玩家a获得差值
            }
            else
            {
                b += y - x;  // 玩家b获得差值
            }
        }
    }
    cout << a << " " << b << endl;
    return 0;
}

【运行结果】

2
10 15
20 10
0 15
posted @ 2026-07-05 17:10  团爸讲算法  阅读(8)  评论(0)    收藏  举报