题意简述

题目背景设定在一个 ASCII 艺术大赛中,三位人工智能选手 GeminiChatGPTClaude 分别提交了作品并获得了三个整数分数 a,b,ca, b, ca,b,c

任务:

给定三个整数 a,b,ca, b, ca,b,c0≤a,b,c≤1000 \le a, b, c \le 1000a,b,c100),分别代表 Gemini、ChatGPT 和 Claude 的得分。

你需要判断比赛结果:

  • 如果某位选手的得分 严格大于 另外两位选手的得分,则输出该选手的名字(Gemini, ChatGPT, 或 Claude)。
  • 如果最高分由两位或两位以上的选手共享(即不存在唯一的最高分),则输出 Draw(平局)。

输入格式:

第一行包含一个整数 ttt,表示测试用例数量。

接下来 ttt 行,每行包含三个整数 a,b,ca, b, ca,b,c

输出格式:

对于每组测试用例,输出一行字符串表示结果。


3. 解题思路

切入点

首先,看数据范围。分数都在 [0,100][0, 100][0,100] 之间,且只有 333 个变量。这意味着我们完全不需要考虑时间复杂度优化,任何 O(1)O(1)O(1) 的逻辑判断都能通过。

这道题的核心在于 逻辑分支的完备性(Completeness of Logic)。很多新手容易写出“漏网之鱼”的 if-else 语句。

试错与推导

我们来模拟一下大脑的判断过程:

  1. 直觉想法: 谁分数大谁赢。
    • 比如 a>ba > ba>ba>ca > ca>c,那肯定是 Gemini 赢。
    • 陷阱: 如果直接写 if (a > b) ... else if (b > c) ...,很容易忽略平局的情况。例如 a=5,b=5,c=3a=5, b=5, c=3a=5,b=5,c=3。这时候 a>ba > ba>b 不成立,但 b>cb > cb>c 成立,如果逻辑不严密,可能会误判 ChatGPT 赢,或者漏掉平局。
  2. 贪心陷阱: 有同学可能想先排序。
    • 如果将数组 [a,b,c][a, b, c][a,b,c] 排序得到 [x,y,z][x, y, z][x,y,z],判断 z>yz > yz>y 是否成立。
    • 虽然可行,但这样会丢失“谁是原始的 a,b,ca, b, ca,b,c”这一信息(除非用结构体排序)。对于仅有 3 个变量的情况,排序反而把问题搞复杂了。
  3. 正确的逻辑路径:
    • 第一步:找出全场的 最高分,记为 max_score=max⁡(a,b,c)max\_score = \max(a, b, c)max_score=max(a,b,c)
    • 第二步:统计有多少人获得了这个最高分。
    • 第三步:
      • 如果只有 1 个人获得最高分 →\to 该选手获胜。
      • 如果有 >1 个人获得最高分 →\to 平局。

算法确定

我们将使用 直接模拟 的方法。为了代码的优雅和可扩展性,我们可以先计算最大值,再通过逻辑与(&&)来判断唯一性。

图解逻辑

为了清晰展示判断流程,请看下图:

代码段

graph TD
    Start[输入 a, b, c] --> CalcMax[计算 max_val = max(a, b, c)]
    CalcMax --> CheckUnique{有多少个变量等于 max_val?}
    CheckUnique -- 1个 --> Who{是谁?}
    Who -- a == max_val --> WinA[输出 Gemini]
    Who -- b == max_val --> WinB[输出 ChatGPT]
    Who -- c == max_val --> WinC[输出 Claude]
    CheckUnique -- 2个或3个 --> Tie[输出 Draw]

4. 代码实现

以下是 C++ 的标准实现。我使用了一种比较简洁的写法:先判断是否平局,再判断谁赢。

C++

/**
 * Codeforces Round #2172 - Problem A: ASCII Art Contest
 * Author: Algorithm Gold Medalist
 * Time Complexity: O(1) per test case
 */

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

void solve() {
    int a, b, c;
    // 读入三个 AI 的分数
    cin >> a >> b >> c;

    // 1. 找出最高分
    int max_score = max({a, b, c});

    // 2. 统计获得最高分的人数
    int count = 0;
    if (a == max_score) count++;
    if (b == max_score) count++;
    if (c == max_score) count++;

    // 3. 根据人数判断结果
    if (count > 1) {
        // 如果有多于1人获得最高分,则是平局
        cout << "Draw" << endl;
    } else {
        // 否则,谁等于最高分谁就是唯一的赢家
        if (a == max_score) {
            cout << "Gemini" << endl;
        } else if (b == max_score) {
            cout << "ChatGPT" << endl;
        } else {
            cout << "Claude" << endl;
        }
    }
}

int main() {
    // 开启 IO 加速,虽然本题数据量小不是必须的,但是个好习惯
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

代码细节点拨:

  • max({a, b, c}): C++11 引入的语法,允许直接对初始化列表求最大值,非常方便。
  • 逻辑分层: 先处理 Draw 的情况(即 count > 1),可以大大简化后续判断赢家的逻辑,不需要再写 a > b && a > c 这种冗长的条件。

5. 复杂度分析 (Complexity)

  • 时间复杂度: O(1)O(1)O(1)
    • 对于每组测试数据,我们只进行了有限次(常数次)的比较和赋值操作,与输入数值的大小无关。
  • 空间复杂度: O(1)O(1)O(1)
    • 我们只使用了 a, b, c, max_score, count 等几个整数变量,不需要额外的数组或数据结构。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐