Description
本次比赛严格按照ACM的排名规则进行,但可能很多小伙伴并不太了解这个排名方法,今天小Z来给大家简单说明一下。每个人的排名根据他解出的题目数量、做题时间还有错误提交次数决定,呃。。。在某些特殊情况下跟大家的昵称也有关系哟~不过不要着急去改昵称,毕竟是特殊情况,很难遇到的。下面我具体说明一下。
- 排名的第一关键字是解出的题目数,也就是说,解出题目数量多的小伙伴一定会排在解出题目数量少的小伙伴前面
- 如果解出的题目数量相同,则根据“罚时”决定排名,罚时少者靠前。罚时是这样定义的:每道成功解出的题目会造成罚时,其他题目不会;每道成功解出的题目造成的罚时是成功解出该题的时间,加上错误提交次数20分钟(比如一道题目在第30分钟解出,之前错误提交了两次,那么总的罚时就是30+20*2=70分钟,这里的错误指的是除了Accept之外的所有反馈情况);最终的罚时是所有成功解出题目的罚时的总和。
- 一道题目正确解出后,再次提交无论结果如何,都不会再对罚时产生任何影响。
- 如果解出的题目数量和罚时数量都相同,在这个平台上就会按照昵称排序。
举个例子,比如当前有5道题目,你成功解出了1,3,5号题目,1号题目在第5分钟1次解出,第3号题目在第10分钟尝试了一次但是wa了,在第15分钟解出;第5号题目在第20分钟解出,之后你又提交了2次;第2号题目你尝试了4次但是都没有解出;第4号题目你没有尝试。那么最终你的罚时是5 + 0 + 15+1*20 + 0 + 20 = 60分钟,你解出了3道题。假设此时有另外三个小伙伴A,B,C,成绩分别是4题75分钟,3题90分钟,2题20分钟,那么最终的排名是A,你,B,C。
好了,现在给你一些提交记录,按照这个规则试着计算一下吧。
Input
第一行包含一个整数T,代表数据组数。
接下来包含T组测试数据。
每组数据第一行包含三个整数n,m,q,分别代表参赛人数、题目数量、提交记录数量。(1<=n,m,q<=10)
紧接着q行,每行包含4个整数p,t,r,s,意思是p号小伙伴在第t分钟提交了r号题目,得到了s的反馈,若s==0则代表错误,s==1代表正确。注意,你的编号就是1号。其他编号的小伙伴只是陪你一起打比赛玩耍的~(1<=p<=n,1<=t<=100,1<=r<=m,s=0或者s=1)
输入保证不存在两个选手,其通过题目数量和罚时相同。
Output
对于每组测试样例,输出一行包含三个整数,分别代表你(1号)的排名、做出的题目数量和罚时。
Sample Input
1
2 5 10
1 5 1 1
1 6 2 0
1 7 2 0
1 8 2 0
1 9 2 0
1 10 3 0
1 15 3 1
1 20 5 1
1 30 5 1
1 35 5 0
Sample Output
1 3 60
Hint
通过结构体数组存储数据,使用cmp函数调用sort对结构体数组进行排序。
题解
#define N 20 #include "cstdio" #include "cstring" #include "cstdlib" #include "iostream" #include "cmath" #include "algorithm" using namespace std; struct Problem { int time[N];//各用户错误次数 }problem[N]; struct Member { int sum;//AC次数 int time;//罚时 int num;//编号 }member[N]; /** * 排名关键字权重 * 1. AC个数 * 2. 罚时 = 解出时间 + 20 * 错误提交个数,只有AC才会计算罚时 * 3. 昵称(不考虑) */ inline bool cmp(Member A, Member B) { //名次从高向低排列 if (A.sum < B.sum || (A.sum == B.sum && A.time > B.time)) return 0; return 1; } int main() { //std::ios_base::sync_with_stdio(false); //std::cin.tie(0); //srand((unsigned int)(time(NULL))); int T; scanf("%d", &T);//T组样例 for (int Case = 0; Case < T; Case++) { /** * n 参赛人数 * m 题目数量 * q 提交记录数量 */ int n, m, q; scanf("%d%d%d", &n, &m, &q); //标记编号方便查询自己 for (int i = 1; i <= n; i++) member[i].num = i; for (int i = 0; i < q; i++) { int p, t, r, s; /** * p 选手id * t 解出时间 * r 题目编号 * s 返回结果 0 错误 1 正确 */ scanf("%d%d%d%d", &p, &t, &r, &s); if (s) { //正确 //处理多次提交正确结果 if (problem[r].time[p] != -1) { member[p].sum++; member[p].time += t + 20 * problem[r].time[p]; problem[r].time[p] = -1;//做标记 } } else { //错误 //处理做对后故意做错 if (problem[r].time[p] != -1) problem[r].time[p]++; } } sort(member + 1, member + n + 1, cmp); for (int i = 1; i <= n; i++) { if (member[i].num == 1) { printf("%d %d %d\n", i, member[i].sum, member[i].time); break; } } memset(problem, 0, sizeof(problem)); memset(member, 0, sizeof(member)); } return 0; }