暑期集训之What Is Your Grade?

来源:互联网 发布:单片机的资源 编辑:程序博客网 时间:2024/06/06 16:26

“Point, point, life of student!” 
This is a ballad(歌谣)well known in colleges, and you must care about your score in this exam too. How many points can you get? Now, I told you the rules which are used in this course. 
There are 5 problems in this final exam. And I will give you 100 points if you can solve all 5 problems; of course, it is fairly difficulty for many of you. If you can solve 4 problems, you can also get a high score 95 or 90 (you can get the former(前者) only when your rank is in the first half of all students who solve 4 problems). Analogically(以此类推), you can get 85、80、75、70、65、60. But you will not pass this exam if you solve nothing problem, and I will mark your score with 50. 
Note, only 1 student will get the score 95 when 3 students have solved 4 problems. 
I wish you all can pass the exam! 
Come on! 
Input
Input contains multiple test cases. Each test case contains an integer N (1<=N<=100, the number of students) in a line first, and then N lines follow. Each line contains P (0<=P<=5 number of problems that have been solved) and T(consumed time). You can assume that all data are different when 0<p. 
A test case starting with a negative integer terminates the input and this test case should not to be processed. 
Output
Output the scores of N students in N lines for each case, and there is a blank line after each case. 
Sample Input
45 06:30:174 07:31:274 08:12:124 05:23:1315 06:30:17-1
Sample Output
100909095100

怎么说,水了四道题发现后面的题都不是很容易的,这道题还是看着大佬的博客写的,很惭愧啊,不过最后还是懂了,至少这个题算是解决了。

这道题其实也是一道排序题,就是排序的东西比较复杂(当然我是不会说我刚开始的时候敲了100多行代码的QAQ),首先要说明一点的是,这个题考查的是最后输出对应同学的成绩,这就有点像稳定排序那道题一样,需要我们来一个归序(就是把顺序再调回来的意思,自己编得一个词)操作,所以我们仍然能像稳定排序一样的设着一个标志来储存顺序,把顺序当成一个变量处理,当然这只是事先要知道的东西,比较难的还是计算得分这个点上,题中的限制条件很多,所以用到了一些我想不到的技巧(刷题刷的少,所以很多东西一时半会想不到),看代码吧,详细解释都在代码里面:

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;struct stu{int s;//做题数目 char t[20];//时间,这里把时间设置成字符串比较起来也比较方便,毕竟只是比较时间大小 int sco;//最终得分 int i;//这个就是顺序储存容器了 ,很重要的一点 }p[111];bool cmp(stu a,stu b)//这个排序是把我们输入的数据来了个调整,做题数目是递减,时间是递增的顺序排的,为了方便计算总得分 {if(a.s!=b.s)return a.s>b.s;elsereturn strcmp(a.t,b.t)<0;}bool cmp1(stu a,stu b)//这个排序就是最后归序的操作了,简单但很不容易想 {return a.i<b.i;//这里也是i小的在前,也就是开始在前面的数据,还是先输出 }int main(){       int n;while(scanf("%d",&n)==1&&n>0){int c[6]={0};//这个数组也非常重要,是把做多少题的同学数量给储存下来了,算是一个优良标准吧,就是多不多加那5分就在这个数组里面体现了,下面会介绍的 for(int i=0;i<n;i++){scanf("%d %s",&p[i].s,p[i].t);p[i].i=i;c[p[i].s]++;//这个数组开始归零操作就是为了这一步,最后会把每种做题情况的人数都分别算出来(比如做对4道的人数) }sort(p,p+n,cmp);//先从优到劣把数据都排好序 for(int i=1;i<5;i++)//这个循环也很关键,是把做题一样的优良都分出来了 {if(c[i]==1)//如果只有一人做对多少题的话不进行操作 continue;c[i]/=2;//如果不只一人的话就把数据处理一下,把前半部分人的人数算出来,也是为了方便计算最后总得分 }for(int i=0;i<n;i++)//计算总得分的循环 {if(p[i].s==5)p[i].sco=100;else if(p[i].s==0)p[i].sco=50;else{int k=1;int l=p[i].s;while(p[i].s==l&&i<n){if(k<=c[l])//这个操作也很巧妙,c[l]这个数组前面的话已经储存了做对N道题的优秀个数(也就是多加5分的人),所以从做题数量仅次于5道的同学开始,k和i同步增大,来进行数据对比,看第i个人在不在优秀范围内,因为一旦k大于这里的c[l]的话就代表这个人已经不能多加5分了 p[i].sco=100-(5-l)*10+5;elsep[i].sco=100-(5-l)*10;k++;i++;}i--;//因为while循环的一个特征,最后会多加一下,所以这里自减放着数据出现问题 }}sort(p,p+n,cmp1);//这就是把数据鬼归序了,很巧妙的一步,其他也就没啥了,把数据原样输出就好了 for(int i=0;i<n;i++)printf("%d\n",p[i].sco);printf("\n"); }return 0;} //希望看到的都能看懂我写的啥QAQ 
自认为还是有点意思的一道题,所以解释了很多,希望都能看懂0.0

原创粉丝点击