暑期集训之What Is Your Grade?

“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
4
5 06:30:17
4 07:31:27
4 08:12:12
4 05:23:13
1
5 06:30:17
-1
Sample Output
100
90
90
95

100

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

这道题其实也是一道排序题,就是排序的东西比较复杂(当然我是不会说我刚开始的时候敲了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;
	else
	return 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;
					else
					p[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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值