zoukankan      html  css  js  c++  java
  • 16-语言入门-16-谁获得了最高奖学金

     
    描述
        某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:
      1) 院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上论文的学生均可获得;
      2) 五四奖学金,每人4000元,期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)的学生均可获得;
      3) 成绩优秀奖,每人2000元,期末平均成绩高于90分(>90)的学生均可获得;
      4) 西部奖学金,每人1000元,期末平均成绩高于85分(>85)的西部省份学生均可获得;
      5) 班级贡献奖,每人850元,班级评议成绩高于80分(>80)的学生干部均可获得;
      只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。
      现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)。

    输入
    第一行输入数据N,表示测试数据组数(0<N<100),每组测试数据输入的第一行是一个整数X(1 <= X <= 100),表示学生的总数。接下来的X行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);是否是学生干部和是否是西部省份学生分别用一个字符表示,Y表示是,N表示不是;发表的论文数是0到10的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。

    输出  每组测试数据输出包括三行,第一行是获得最多奖金的学生的姓名,第二行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。第三行是这X个学生获得的奖学金的总数。

    样例输入
    1
    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

    样例输出
    ChenRuiyi
    9000
    28700
     
     
    代码:
     
    #include <stdio.h>

    typedef struct _Student
    {
         //姓名
         char name[20];
         //期末平均成绩
         int grade;
         //班级评议成绩
         int assessment;
         //是否是学生干部 Y-是 N-不是
         char isLeader;
         //是否是西部省份学生 Y-是 N-不是
         char isWest;
         //发表的论文数
         int paperCount;
         //奖金总数
         int reward;
    }Student;

    static void calAllReward(Student *student);

    int main()
    {
         int readLen = 0;
         scanf("%d",&readLen);
         getchar();
        
         while(readLen > 0)
         {
              int studentCount = 0;
              scanf("%d",&studentCount);
              getchar();
             
              Student resultStudent={0};
              int resultScore = 0;
             
              while(studentCount > 0)
              {
                   Student inputStudent = {0};
                   scanf("%s %d %d %c %c %d",inputStudent.name,&inputStudent.grade,&inputStudent.assessment,&inputStudent.isLeader,
                   &inputStudent.isWest,&inputStudent.paperCount);
                   getchar();
                  
                   calAllReward(&inputStudent);
                   if(inputStudent.reward > resultStudent.reward)
                   {
                        resultStudent = inputStudent;
                   }
                  
                   resultScore += inputStudent.reward;
             
                   --studentCount;
              }
             
              printf("%s %d %d ",resultStudent.name,resultStudent.reward,resultScore);
              --readLen;
         }
        
         return 0;
    }

    static void calAllReward(Student *student)
    {
         student->reward = 0;
         if(student->grade > 80 && student->paperCount > 0)
         {
              student->reward += 8000;
         }
        
         if(student->grade > 85)
         {
              if(student->assessment > 80)
              {
                   student->reward += 4000;
              }
             
              if(student->isWest == 'Y')    
              {
                   student->reward += 1000;
              }
         }
        
         if(student->grade > 90)
         {
              student->reward += 2000;
         }
        
         if(student->assessment > 80 && student->isLeader == 'Y')
         {
              student->reward += 850;
         }
    }

     
    分析容易出错内容:
    笔者在做此题的过程中先后提交了9个版本,最终第9个版本最终找到了问题所在,通过,回顾解题过程,甚是惭愧。
     
    1.题意理解错误。以为是输入一个数组代表要录入几个学生就结束了。看到了示例数据中的第一个输入1,以为是出错题了。直到提交了2个版本后,才发现原来第一个数字代表的是要测试多少组数据。
     
    2.由于第一条的原因,导致结果保存的临时对象
      Student resultStudent={0};
      int resultScore = 0;
     
    放在了第一层
    while(readLen>0)
    {
         ...
    }
    之外
    这就导致了第一组数据是正确的,但是第二组的总分会累加,最好的学生奖学金如果没有超过第一个就还会显示第一个,也就是每一组的数据计算后并没有清空。
    这个问题很难发现,因为一直尝试使用给出的数据进行测试,都正确无误。
     
    这就给我两个提示:
    1.一定要搞清楚问题本身
    2.变量的作用域一定要最小化
    3.出错的时候,要从输入的数据入手,分析可能产生的问题。
     
     
  • 相关阅读:
    2021NUAA暑假集训 Day3 题解
    2021NUAA暑假集训 Day2 题解
    2021NUAA暑期模拟赛部分题解
    CodeForces 1038D Slime
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 10689 Yet another Number Sequence
    HDU 4549 M斐波那契数列
    HDU 4990 Reading comprehension
    CodeForces 450B Jzzhu and Sequences
  • 原文地址:https://www.cnblogs.com/sharpfeng/p/5141721.html
Copyright © 2011-2022 走看看