1 条题解

  • 0
    @ 2026-4-24 9:59:08

    题目分析

    这是一道模拟题,需要根据给定的条件计算每个学生的奖学金总额,然后找出获得奖学金最多的学生(如果有并列,输出最先出现的学生),并计算所有学生的奖学金总和。

    解题思路

    1. 数据读取:读入学生人数 N,然后循环读入每个学生的信息
    2. 条件判断:按照题目给出的 5 个条件,逐一判断并累计奖学金
    3. 记录最大值:在计算每个学生奖学金时,记录最大值和对应的学生姓名
    4. 累加总和:同时累加所有学生的奖学金总额

    条件详解

    需要特别注意条件中的比较运算符:

    • 条件1:期末平均成绩 > 80 且 论文数 >= 1 → 8000 元
    • 条件2:期末平均成绩 > 85 且 班级评议成绩 > 80 → 4000 元
    • 条件3:期末平均成绩 > 90 → 2000 元
    • 条件4:期末平均成绩 > 85 且 西部省份学生 → 1000 元
    • 条件5:班级评议成绩 > 80 且 学生干部 → 850 元

    注意:所有条件都是严格大于(>),没有等于的情况。

    代码实现

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        int N;
        cin >> N;
        
        string maxName;      // 获得最多奖学金的学生姓名
        int maxMoney = -1;   // 最多奖学金金额
        int totalMoney = 0;  // 所有学生奖学金总和
        
        for (int i = 0; i < N; i++) {
            string name;
            int avgScore, classScore, paperNum;
            char isCadre, isWest;
            
            // 读入学生信息
            cin >> name >> avgScore >> classScore >> isCadre >> isWest >> paperNum;
            
            // 计算该学生的奖学金
            int money = 0;
            
            // 1. 院士奖学金:8000元
            if (avgScore > 80 && paperNum >= 1) {
                money += 8000;
            }
            
            // 2. 五四奖学金:4000元
            if (avgScore > 85 && classScore > 80) {
                money += 4000;
            }
            
            // 3. 成绩优秀奖:2000元
            if (avgScore > 90) {
                money += 2000;
            }
            
            // 4. 西部奖学金:1000元
            if (avgScore > 85 && isWest == 'Y') {
                money += 1000;
            }
            
            // 5. 班级贡献奖:850元
            if (classScore > 80 && isCadre == 'Y') {
                money += 850;
            }
            
            // 更新最大值(注意:如果有并列,保留先出现的)
            if (money > maxMoney) {
                maxMoney = money;
                maxName = name;
            }
            
            // 累加总奖学金
            totalMoney += money;
        }
        
        // 输出结果
        cout << maxName << endl;
        cout << maxMoney << endl;
        cout << totalMoney << endl;
        
        return 0;
    }
    

    关键点说明

    1. 最大值初始化:将 maxMoney 初始化为 -1,确保第一个学生的奖学金一定能成为最大值(因为奖学金最少为 0,-1 < 0)

    2. 并列处理:只有当 money > maxMoney 时才更新,这样如果奖学金相等,不会更新,保留了先出现的学生

    3. 字符比较:判断 isCadre == 'Y'isWest == 'Y',注意是字符比较,不是字符串

    4. 数据类型:使用 int 类型存储奖学金金额,题目数据范围较小,不会溢出

    测试样例

    输入:

    4
    YaoLin 87 82 Y N 0
    ChenRuiyi 88 78 N Y 1
    LiXin 92 88 N N 0
    ZhangQin 83 87 Y N 1
    

    计算过程:

    • YaoLin:条件2(87>85且82>80)得4000,条件5(82>80且是干部)得850,共计4850
    • ChenRuiyi:条件1(88>80且论文≥1)得8000,条件4(88>85且是西部)得1000,共计9000
    • LiXin:条件3(92>90)得2000,共计2000
    • ZhangQin:条件5(87>80且是干部)得850,条件2?不满足(87≤85?实际上是87>85但评议87>80,应该满足条件2),需要仔细判断:
      • avgScore=83>85? 否,所以不满足条件2和条件4
      • 条件1:83>80且论文≥1,满足!得8000
      • 条件5:87>80且是干部,满足!得850
      • 共计8850

    所以最多的是 ChenRuiyi,9000元,总和=4850+9000+2000+8850=24700?样例输出是28700,说明我的计算有误。

    重新计算:

    • YaoLin: 87>85且82>80 → 4000, 82>80且干部Y → 850, 共计4850 ✓
    • ChenRuiyi: 88>80且论文1 → 8000, 88>85且西部Y → 1000, 共计9000 ✓
    • LiXin: 92>90 → 2000,共计2000 ✓
    • ZhangQin: 83>80且论文1 → 8000, 83>85? 否,87>80且干部Y → 850, 共计8850

    总和 = 4850 + 9000 + 2000 + 8850 = 24700,但样例输出是28700,差4000。

    发现问题了!ZhangQin 的条件判断:

    • 期末83分,班级87分
    • 条件1:83>80且论文数1≥1 → 8000 ✓
    • 条件2:83>85? 否 (83不大于85)
    • 条件3:83>90? 否
    • 条件4:83>85? 否
    • 条件5:87>80且干部Y → 850 ✓ 小计 8850

    但我们还漏了什么?仔细看题:ChenRuiyi 获得 9000,YaoLin 获得 4850,LiXin 获得 2000,ZhangQin 获得 8000+850=8850 总和 = 9000+4850+2000+8850 = 24700 但样例是 28700,差 4000。

    说明 ZhangQin 还有 4000 元的奖学金。条件2?83>85 不满足。条件4?83>85 不满足。所以不是。

    等等,可能我误读了输入数据?让我重新看样例输入:

    4
    YaoLin 87 82 Y N 0
    ChenRuiyi 88 78 N Y 1
    LiXin 92 88 N N 0
    ZhangQin 83 87 Y N 1
    

    ZhangQin 的期末是 83,不是 83>85,所以不满足条件2和4。但题目说"ChenRuiyi"是 9000,那么总奖金 28700,减去其他人的: 28700 - (4850+9000+2000) = 28700 - 15850 = 12850,但 ZhangQin 不可能得到 12850。

    说明我的计算有误,可能是因为"ChenRuiyi"是9000,但不是最大值?最大值是ZhangQin?但样例输出第一行是ChenRuiyi,说明他仍然是最大值。

    或者我漏算了条件?条件1:期末>80且论文≥1 → 8000 条件2:期末>85且班级>80 → 4000 条件3:期末>90 → 2000 条件4:期末>85且西部Y → 1000 条件5:班级>80且干部Y → 850

    YaoLin: 87,82,Y,N,0

    • 条件2:87>85且82>80 ✓ → 4000
    • 条件5:82>80且干部Y ✓ → 850
    • 条件1? 87>80但论文0 ✗
    • 条件3? 87>90 ✗
    • 条件4? 87>85但西部N ✗ 合计4850 ✓

    ChenRuiyi: 88,78,N,Y,1

    • 条件1:88>80且论文1 ✓ → 8000
    • 条件4:88>85且西部Y ✓ → 1000
    • 条件2? 88>85但班级78>80? ✗
    • 条件3? 88>90 ✗
    • 条件5? 干部N ✗ 合计9000 ✓

    LiXin: 92,88,N,N,0

    • 条件3:92>90 ✓ → 2000
    • 条件2? 92>85且88>80 ✓ → 4000 (这里我漏算了!)
    • 条件1? 92>80但论文0 ✗
    • 条件4? 92>85但西部N ✗
    • 条件5? 干部N ✗ 合计6000,不是2000!

    ZhangQin: 83,87,Y,N,1

    • 条件1:83>80且论文1 ✓ → 8000
    • 条件5:87>80且干部Y ✓ → 850
    • 条件2? 83>85 ✗
    • 条件3? 83>90 ✗
    • 条件4? 83>85 ✗ 合计8850

    现在总和 = 4850 + 9000 + 6000 + 8850 = 28700 ✓ 最大值 = max(4850,9000,6000,8850) = 9000,学生是 ChenRuiyi ✓

    所以正确的代码就是对每个条件逐一判断,注意不要遗漏条件。

    总结

    本题是 NOIP 提高组的签到题,主要考察:

    1. 条件判断的准确性
    2. 数据读入和处理
    3. 最大值的记录和输出
    • 1

    [NOIP 2005 提高组] 谁拿了最多奖学金

    信息

    ID
    7
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    2
    已通过
    2
    上传者