ACM练习 小Z来讲排名规则(WA)【C++ stable_sort稳定排序】

描述

本次比赛严格按照ACM的排名规则进行,但可能很多小伙伴并不太了解这个排名方法,今天小Z来给大家简单说明一下。每个人的排名根据他解出的题目数量、做题时间还有错误提交次数决定,呃。。。在某些特殊情况下跟大家的昵称也有关系哟~不过不要着急去改昵称,毕竟是特殊情况,很难遇到的。下面我具体说明一下。

  1. 排名的第一关键字是解出的题目数,也就是说,解出题目数量多的小伙伴一定会排在解出题目数量少的小伙伴前面

  2. 如果解出的题目数量相同,则根据“罚时”决定排名,罚时少者靠前。罚时是这样定义的:每道成功解出的题目会造成罚时,其他题目不会;每道成功解出的题目造成的罚时是成功解出该题的时间,加上错误提交次数20分钟(比如一道题目在第30分钟解出,之前错误提交了两次,那么总的罚时就是30+202=70分钟,这里的错误指的是除了Accept之外的所有反馈情况);最终的罚时是所有成功解出题目的罚时的总和。

  3. 一道题目正确解出后,再次提交无论结果如何,都不会再对罚时产生任何影响。

  4. 如果解出的题目数量和罚时数量都相同,在这个平台上就会按照昵称排序。

举个例子,比如当前有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。

好了,现在给你一些提交记录,按照这个规则试着计算一下吧。

输入

第一行包含一个整数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)
输入保证不存在两个选手,其通过题目数量和罚时相同。

输出

对于每组测试样例,输出一行包含三个整数,分别代表你(1号)的排名、做出的题目数量和罚时

样例输入

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

样例输出

1 3 60

提交总是WA,不知道错在哪了。题目给的测试用例和我自己写的测试用例都能按照预期运行,是我理解错题意了吗,还是细节/边界问题?还是数组数组大小不够?

我写的测试用例如下:

测试用例1

1
2 5 12
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 11 3 0
1 15 3 1
1 16 3 1
1 20 5 1
1 30 5 1
1 35 5 0
答案:1 3 80

测试用例2

1
2 5 10
1 5 1 1
1 10 3 0
1 15 3 1
1 20 5 1
1 16 3 0
1 9 2 0
1 35 5 0
1 30 5 1
1 7 2 0
1 17 4 1
答案:1 3 77

测试用例3

1
2 5 9
1 1 1 0
2 1 2 1
1 2 2 0
2 2 2 0
2 2 3 0
2 3 3 1
1 3 1 0
1 4 2 0
1 5 1 1
//1 对1 题 时间20*2+5=45
//2 对2 题 时间1+20+3=24
答案:2 1 45

测试用例4

1
3 5 10
1 1 1 0
2 1 2 1
1 2 2 0
2 2 2 0
2 2 3 0
2 3 3 1
1 3 1 0
3 4 1 1
1 4 2 1
1 5 1 1
//1 对2 题 时间20*2+20+5+4=69
//2 对2 题 时间1+20+3=24
//3 对1题 时间 4
答案:2 2 69

测试用例5

1
5 2 10
1 1 1 0
2 10 4 0
3 20 5 1
4 30 2 1
5 40 1 1
1 50 2 0
2 60 4 1
3 70 5 0
4 80 3 1
5 90 2 1
//1 对0 时0
//2 对1 时60+20=80
//3 对1 时20
//4 对2 时30+80=110
//5 对2 时40+90=130
答案:1 0 0

代码

//排名关键字:
//1 解出的题目数
//2 罚时:解答时间+错误次数*20min
//3 昵称
#include<iostream>
#include<algorithm>
using namespace std;

class oneTry
{
public:
	int peopleNum;
	int time;
	int questionNum;
	int result;
	int wrongTime = 0;
};

class onePeople
{
public:
	int waQues[100] = { 0 };//尝试某题的次数
	int quesOK[100] = { 0 };//本题是否通过
	int pNum = 0;//人的序号
	int accept = 0;//成功题数
	int pTime = 0;//罚时
};

int compareQuesNum(oneTry a1, oneTry a2)
{
	return (a1.questionNum < a2.questionNum);
}

int compareTryTime(oneTry a1, oneTry a2)
{
	return (a1.time < a2.time);
}

int compareTime(onePeople a1, onePeople a2)
{
	return (a1.pTime < a2.pTime);
}

int compareAcc(onePeople a1, onePeople a2)
{
	return (a1.accept > a2.accept);
}

int main()
{
	//轮数
	int play;
	cin >> play;

	//人数 题目数量 提交记录数量
	int totalPeople, totalQuestion, totalTry;
	cin >> totalPeople >> totalQuestion >> totalTry;

	//输入每一次尝试结果
	oneTry onetry[15];
	int i;
	for (i = 0; i < totalTry; i++)
	{
		cin >> onetry[i].peopleNum >> onetry[i].time >> onetry[i].questionNum >> onetry[i].result;
	}

	//题号排序
	stable_sort((onetry + 0), (onetry + totalTry), compareQuesNum);

	//时间排序
	stable_sort((onetry + 0), (onetry + totalTry), compareTryTime);

	//计算每个人的罚时
	int j;
	onePeople onepeople[100];

	for (j = 0; j < totalPeople; j++)//遍历每个人
	{
		onepeople[j].pNum = j + 1;
		for (i = 0; i < totalTry; i++)//查找所有这个人的提交记录
		{
			if (onetry[i].peopleNum == onepeople[j].pNum)//是当前人的提交记录
			{
				if (onepeople[j].quesOK[onetry[i].questionNum] == 1)//已经通过
				{
					continue;
				}
				else//未通过
				{
					if (onetry[i].result == 0)//提交失败
					{
						onepeople[j].waQues[onetry[i].questionNum]++;//尝试次数++
					}
					else//提交成功
					{
						onepeople[j].accept++;
						onepeople[j].quesOK[onetry[i].questionNum] = 1;//标记通过
						onepeople[j].pTime += onepeople[j].waQues[onetry[i].questionNum] * 20 + onetry[i].time;//计算时间
					}
				}
			}
		}
	}

	//给人排序,先排罚时 注意排序稳定性
	stable_sort((onepeople + 0), (onepeople + totalPeople), compareTime);

	//排答对数量
	stable_sort((onepeople + 0), (onepeople + totalPeople), compareAcc);

	//计算排名
	int myrand;
	for (i = 0; i < totalPeople; i++)
	{
		if (onepeople[i].pNum == 1)
		{
			myrand = i;
		}
	}

	//输出
	cout << myrand + 1 << ' ' << onepeople[myrand].accept << ' ' << onepeople[myrand].pTime;
	system("pause");
}

猜你喜欢

转载自blog.csdn.net/sinat_42483341/article/details/89219883