题目链接:https://ac.nowcoder.com/acm/contest/903/D
解题心得:
- 上次我们学院院赛我队友就出了个和这个几乎一毛一样的题去恶心参赛人员,结果这次居然遇到和我队友想法一样的出题人了。
- 其实很简答就是模拟榜单嘛,写的时候把代码写规范一点,脑子不要发昏认认真真写就行了。写完一发AC。
#include <bits/stdc++.h>
using namespace std;
map <string, int> map_name;
int id, max_name_len, n;//记录有多少个人进行了有效提交,有效队伍名字最长的长度,题目数量
struct Person {//把每个队伍单独抽象出来
int penalty, solved;//记录罚时次数,解决了多少个题
string name;//记录名字
bool if_pass[50];//记录每个题是否通过了
int each_penelty[50];//每个题被罚时次数
bool operator < (const Person& y) const {//排名
Person x = *this;
if(x.solved != y.solved)
return x.solved > y.solved;
else// if(x.penalty != y.penalty)
return x.penalty < y.penalty;
}
}p[5010];
bool cmp(Person x, Person y) {
if(x.solved != y.solved)
return x.solved > y.solved;
else if(x.penalty != y.penalty)
return x.penalty < y.penalty;
// if(x.name != y.name)
return x.name < y.name;
}
void checke_sigal(char s[]) {//对每一条记录进行处理
int h, m;
sscanf(s, "%d:%d", &h, &m);
m = h*60 + m;//提交时间
int w = int(s[6] - 'A');
int result = -1, Next_pos = -1;//记录结果结果编号和题目中给出的对应,下一个需要寻找的信息在字符串中的位置
if(s[8] == 'A') {
result = 1;
Next_pos = 8 + strlen("Accepted ");
} else if(s[8] == 'W') {
result = 2;
Next_pos = 8 + strlen("Wrong Answer ");
} else if(s[8] == 'T') {
result = 3;
Next_pos = 8 + strlen("Time Limit Exceeded ");
} else if(s[8] == 'C') {//CE看作无效提交,直接不处理,首先排除掉
return ;
} else if(s[8] == 'M') {
result = 5;
Next_pos = 8 + strlen("Memory Limit Exceeded ");
} else if(s[8] == 'O') {
result = 6;
Next_pos = 8 + strlen("Output Limit Exceeded ");
} else if(s[8] == 'R') {
result = 7;
Next_pos = 8 + strlen("Runtime Error ");
} else if(s[8] == 'P') {
result = 8;
Next_pos = 8 + strlen("Presentation Error ");
}
string name = s+Next_pos;//记录队伍名字
if(map_name.count(name) == 0) {
map_name[name] = ++id;
}
int which = map_name[name];
p[which].name = name;
max_name_len = max(max_name_len, int(name.length()));
if(p[which].if_pass[w]) return ;
if(result == 1) {//AC了
p[which].if_pass[w] = true;
p[which].penalty += p[which].each_penelty[w]*20 + m;
p[which].solved ++;
} else {//除了AC都罚时
p[which].each_penelty[w]++;
}
}
void Print(string ss, int cnt) {
cout<<ss;
for(int i=0;i<cnt;i++) {
printf(" ");
}
}
void Print() {//按照格式打印就行了
string ss;
Print(ss="Rank", 2);
Print(ss="Who", max_name_len-3+2);
Print(ss="Solved", 2);
Print(ss="Penalty", 0);
for(int i=0;i<n;i++) {
printf(" %c", 'A' + i);
}
printf("\n");
int rank;
for(int i=1;i<=id;i++) {
rank = lower_bound(p+1, p+1+id, p[i]) - p;//排名直接lower_bound找就行了
printf("%4d ", rank);
Print("", max_name_len-p[i].name.length());
printf("%s ",p[i].name.c_str());
printf("%6d ",p[i].solved);
printf("%7d", p[i].penalty);
for(int j=0;j<n;j++) {
if(!p[i].if_pass[j]) {
if(p[i].each_penelty[j] == 0)
printf(" ");
else
printf(" -%d", p[i].each_penelty[j]);
} else {
if(p[i].each_penelty[j] == 0) {
printf(" +");
} else {
printf(" +%d", p[i].each_penelty[j]);
}
}
}
printf("\n");
}
}
int main() {
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
scanf("%d", &n);
getchar();
char record[2100];
while(fgets(record, 2100, stdin)) {
int len=strlen(record);
record[len-1] = 0;
if(record[0] == 'G') break;
checke_sigal(record);
}
sort(p+1, p+1+id, cmp);
Print();
return 0;
}