Background
In the ACM/ICPC Regional Contest, all the teams are ranked according to the most problems solved. For the purposes of awards, or in determining qualifier(s) for the World Finals, teams who solve the same number of problems are ranked by least total time. The total time is the sum of the time consumed for each problem solved. The time consumed for a solved problem is the time elapsed from the beginning of the contest to the submittal of the first accepted run plus 20 penalty minutes for every rejected run for that problem regardless of submittal time. There is no time consumed for a problem that is not solved. If there is still a tie, rank them in lexicographic order. There are always 9 problmes marked by A to I for a Regional Contest. The contest starts at 9:00 and ends at 14:00. Now, given the submissions of all teams in time order, please print the final ranklist.
Multiple test cases, each starts with two positive integer, N (10 <= N <= 100) and M (20 <= M <= 10000), where N is the number of the teams and M is the number of the submissions during the contest. The names (composed by only dights and letters, length is no more than 20) of the N teams come in the following N lines. And then, there are M lines, each line tells a submission, in the form of "Problem Time(XX:XX:XX) Jundgement(maybe one of AC, WA, TLE, MLE, CE, RE and PE, only AC means the right answer) TeamName".
For each case, print the final ranklist in N lines, each line contains only a team name. Print a blank line after each case.
10 26
liulei
CaiSOFT
o0o
icecream
davidloves
WorldWar3
iaag88
yukui0716
xunxun
rainbowrain
E 09:28:40 WA liulei
A 09:39:18 TLE CaiSOFT
E 09:39:48 WA liulei
A 09:41:48 AC CaiSOFT
E 09:42:57 WA o0o
B 09:47:14 WA icecream
B 10:06:11 RE CaiSOFT
D 10:09:15 WA icecream
B 10:09:25 AC CaiSOFT
E 10:12:05 AC liulei
C 10:15:34 AC davidloves
B 10:32:27 WA WorldWar3
C 10:37:35 WA CaiSOFT
C 10:38:38 AC CaiSOFT
C 10:50:06 AC iaag88
B 10:50:33 AC liulei
B 10:57:48 WA WorldWar3
B 11:03:33 AC iaag88
D 11:07:49 AC CaiSOFT
D 11:07:53 WA yukui0716
B 11:16:37 WA WorldWar3
E 11:18:30 AC CaiSOFT
E 11:35:54 TLE iaag88
E 11:40:25 WA davidloves
E 11:52:34 WA iaag88
B 11:59:34 AC icecream
CaiSOFT
liulei
iaag88
davidloves
icecream
o0o
rainbowrain
WorldWar3
xunxun
yukui0716
题目大意:
给定ACM/ICPC Regional的比赛评判规则,多组输入,输入n个队在比赛过程中的k次提交情况,判断每队排名。
分析:
水题,输入时连续输入就行,不过此题的排序规则需要仔细考虑:
注意这道题的猥琐数据可能就在1次AC之后该队还可能继续交这道题,对的话注意不能更新时间,错的话也不再计算罚时!
实现:
将每个队的情况用一个map保存,再用另一个string数组保存队名用于排序,用结构体PROB保存每队每道题的耗时,罚时次数以及是否AC,用TEAM结构体存储一个队的九道题的具体情况,在其中有成员函数getScroe()和getTime()分别计算题数和罚时。输入时只需判断一道题是否AC,分类处理即可。最后直接按指定规则对string数组进行sort并输出即可,其中用时很好计算,将六十进制数转为十进制加减就可以,而罚时次数每次加一。
每组数据末输出一行空格这个小细节,我总是会忘掉。
此处对于HOJ发一下小小的感叹,HOJ上面cctype和cstring里面许多函数不能使用,在这里忽略大小写的字符串比较需要自己写转化和比较函数。
本来想用hash存队伍,也就可以直接把队名写在TEAM里,但是考虑到小范围数据用小素数模可能会冲突比较大,用大素数的话又占空间多,最后选择了用STL的map容器,以后有空了可以用字典树尝试重写一下程序,希望会有新的体会。
代码:
#include <iostream> #include <cstring> #include <cctype> #include <map> using namespace std; struct PROB { int rejects; int time; bool ac; PROB() { rejects = 0; time = 0; ac = false; } }; struct TEAM { PROB doing[9]; int getTime() { int time = 0; for (int i = 0; i < 9; i++) { if (doing[i].ac) time += doing[i].time + doing[i].rejects * 20 * 60; } return time; } int getScore() { int score = 0; for (int i = 0; i < 9; i++) if (doing[i].ac) score++; return score; } }; typedef map<string, TEAM> Team; Team team; string StrLow(string a) { int len = a.length(); for (int i = 0; i < len; i++) if (isalpha(a[i])) a[i] |= 0x20; return a; } bool StrICmp(string a, string b) { string x = StrLow(a), y = StrLow(b); return x < y; } bool cmp(string a, string b) { if (team[a].getScore() != team[b].getScore()) return team[a].getScore() > team[b].getScore(); if (team[a].getTime() != team[b].getTime()) return team[a].getTime() < team[b].getTime(); return StrICmp(a, b); } int main( ) { const int time0 = 32400; int n, m, len; string tm[200]; while (scanf("%d %d", &n, &m) != EOF) { team.clear(); len = 0; string name, res; char p; int hh, mm, ss, time; for (int i = 0; i < n; i++) { cin >> name; TEAM tmp; team[name] = tmp; tm[len++] = name; } for (int i = 0; i < m; i++) { scanf("%*c%c %d:%d:%d", &p, &hh, &mm, &ss); cin >> res >> name; time = hh * 3600 + mm * 60 + ss; if (!team[name].doing[p - 'A'].ac) { if (res == "AC") { team[name].doing[p - 'A'].ac = true; team[name].doing[p - 'A'].time = time - time0; } else { team[name].doing[p - 'A'].rejects++; } } } sort(tm, tm + n, cmp); for (int i = 0; i < n; i++) cout << tm[i] << endl; cout << endl; } }