1 条题解

  • 0
    @ 2025-11-27 11:19:28

    题目分析

    问题重述

    比较两个选手的比赛成绩:

    • 每个选手有18道题的得分(0-10分)
    • 比较规则:
      1. 总分高的排名靠前
      2. 总分相同,得10分的题目数量多的排名靠前
      3. 如果还相同,比较得9分的题目数量,依此类推
      4. 如果所有分数分布都相同,则为平局

    关键观察

    这是一个典型的多关键字排序问题,需要按照特定优先级比较两个选手的成绩。

    解法思路

    方法:模拟比较过程

    步骤1:计算总分

    分别计算Algosia和Bajtek的总分

    步骤2:按优先级比较

    如果总分相同,按照分数从高到低(10, 9, 8, ..., 0)的顺序比较各个分数段的人数。

    步骤3:输出结果

    根据比较结果输出获胜者或平局。

    代码实现

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    int main() {
        vector<int> algosia(18), bajtek(18);
        
        // 读取Algosia的成绩
        for (int i = 0; i < 18; i++) {
            cin >> algosia[i];
        }
        
        // 读取Bajtek的成绩  
        for (int i = 0; i < 18; i++) {
            cin >> bajtek[i];
        }
        
        // 计算总分
        int sum_algosia = 0, sum_bajtek = 0;
        for (int i = 0; i < 18; i++) {
            sum_algosia += algosia[i];
            sum_bajtek += bajtek[i];
        }
        
        // 第一优先级:总分比较
        if (sum_algosia > sum_bajtek) {
            cout << "Algosia" << endl;
            return 0;
        } else if (sum_algosia < sum_bajtek) {
            cout << "Bajtek" << endl;
            return 0;
        }
        
        // 第二优先级:按分数段从高到低比较
        for (int score = 10; score >= 0; score--) {
            int count_algosia = 0, count_bajtek = 0;
            
            // 统计该分数段的人数
            for (int i = 0; i < 18; i++) {
                if (algosia[i] == score) count_algosia++;
                if (bajtek[i] == score) count_bajtek++;
            }
            
            // 比较该分数段的人数
            if (count_algosia > count_bajtek) {
                cout << "Algosia" << endl;
                return 0;
            } else if (count_algosia < count_bajtek) {
                cout << "Bajtek" << endl;
                return 0;
            }
        }
        
        // 所有比较都相同,平局
        cout << "remis" << endl;
        
        return 0;
    }
    

    优化实现

    使用更简洁的统计方法:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    int main() {
        vector<int> a(18), b(18);
        
        // 读取输入
        for (int i = 0; i < 18; i++) cin >> a[i];
        for (int i = 0; i < 18; i++) cin >> b[i];
        
        // 计算总分
        int sum_a = 0, sum_b = 0;
        for (int i = 0; i < 18; i++) {
            sum_a += a[i];
            sum_b += b[i];
        }
        
        // 总分比较
        if (sum_a != sum_b) {
            cout << (sum_a > sum_b ? "Algosia" : "Bajtek") << endl;
            return 0;
        }
        
        // 分数分布比较(从10分到0分)
        for (int s = 10; s >= 0; s--) {
            int cnt_a = 0, cnt_b = 0;
            for (int i = 0; i < 18; i++) {
                if (a[i] == s) cnt_a++;
                if (b[i] == s) cnt_b++;
            }
            if (cnt_a != cnt_b) {
                cout << (cnt_a > cnt_b ? "Algosia" : "Bajtek") << endl;
                return 0;
            }
        }
        
        // 完全平局
        cout << "remis" << endl;
        
        return 0;
    }
    

    样例验证

    用题目样例验证:

    输入:

    10 10 7 10 10 10 10 10 10 10 10 10 0 10 4 10 10 10
    10 10 10 10 10 10 10 10 10 10 10 10 4 3 4 10 10 10
    

    计算过程:

    1. 总分比较:两人都是161分
    2. 10分数量比较:Algosia有14个10分,Bajtek有13个10分
    3. 因此Algosia获胜

    算法总结

    1. 多关键字排序:按照总分→10分数量→9分数量→...→0分数量的优先级比较
    2. 提前终止:一旦在某级比较中分出胜负就立即返回结果
    3. 简单模拟:直接按照题目描述的规则实现

    复杂度分析

    • 时间复杂度O(18×11)=O(198)O(18 \times 11) = O(198),常数时间
    • 空间复杂度O(36)O(36),只需要存储两个选手的成绩

    关键技巧

    1. 优先级顺序:严格按照题目要求的比较顺序
    2. 循环设计:从高分到低分依次比较
    3. 提前返回:一旦确定结果就立即返回,避免不必要的计算

    这道题主要考察对多关键字排序规则的理解和实现能力,难度较低但需要仔细处理比较逻辑。

    • 1

    信息

    ID
    5647
    时间
    2000ms
    内存
    1024MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者