题目大意:本题是模拟ACM比赛中的排名规则,根据所给的信息来输出一个Final Standings(最后的榜单)!!
规则如下:
1,排名按照AC的题数降序排列;
2,AC了同样的题数,那么就按照解题的Total penalty time升序排列(花的时间少肯定排前)
3,如果排名一样(意思是AC题数和总时间都一样),就按照队名的字典序升序排列,但是注意which should be case-insensitive
(不分大小写)
另外:
1,一个题目被solved 仅当获得AC
2,一个题目的Penalty time
是第一次AC时候的elapsed time (就是从开始到AC的那个时间,也就是输入案例每一行的第一个数)和其他判断时候罚时的总和(每次不AC罚时20)
3,一个队伍的Total penalty
time 是所有题目中的被solved时的Penalty time
4,只有一个队伍至少AC 1个题目时才能被输出到榜单上!
Sample Input
3
30 Fatmouse 1 WA
32 Killer 2 AC
39 Turing 3 RE
56 Fatmouse 2 CE
63 Turing 3 AC
77 Killer 1 PE
79 Killer 1 AC
83 ZzZzZ 3 AC
89 Fatmouse 3 OLE
89 Chenyue 3 AC
Sample Output
由于网页上案例好像排列不方便看,这里贴出我的测试输出文档截图
需要注意的地方:
想不到学ACM这么久,我还是通过这个题目才了解到ACM比赛中的具体成绩规则!!!!
一个题目只有当AC之后,它的罚时才会被加到总时间里面去,不然罚时会被忽略!!!!
------------------------------------------------------------------------------------------------------------------------------------
解决方法:
关于队名,这里用一个map映射,每个队伍用struct保存
struct 里面包括
int AC;//AC题数
int tol_time;//总时间
string team_name;//队名
int problem[PRO_MAX];//初始0,每次不AC就-20表示一次没过罚时,AC了才把所有的时间加到tol_time,并且赋值1
bool operator<(const team_node& T)const
{
if(T.AC != AC) return AC > T.AC;//AC数降序
else if(tol_time != T.tol_time) return tol_time < T.tol_time;//总时间升序
else return mycmp(team_name,T.team_name);//按名字字典序比较
}
------------------------------------------------------------------------------------------------------------------------------------------
代码:
#include <map> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define TEAM_MAX 10005 #define PRO_MAX 105 int team_sum;//总的队数 bool mycmp(string a,string b)//统一换成大写比较 { for(int i = 0; i < a.length(); i ++) if(a[i] > ‘Z‘) a[i] -= 32; for(int i = 0; i < b.length(); i ++) if(b[i] > ‘Z‘) b[i] -= 32; return a<b; } struct team_node { int AC; int tol_time; string team_name; int problem[PRO_MAX];//初始0,每次不AC就-20表示一次没过罚时,AC了才把所有的时间加到tol_time,并且赋值1 bool operator<(const team_node& T)const { if(T.AC != AC) return AC > T.AC;//AC数降序 else if(tol_time != T.tol_time) return tol_time < T.tol_time;//总时间升序 else return mycmp(team_name,T.team_name);//按名字字典序比较 } }TEAM[TEAM_MAX]; void print() { int rank = 1; if(TEAM[0].AC == 0) return ; printf("%-10d%-30s%-10d%d\n",rank,TEAM[0].team_name.c_str(),TEAM[0].AC,TEAM[0].tol_time); for(int i = 1; i < team_sum; i ++) { rank++; if(TEAM[i].AC == 0) return ; if(TEAM[i].AC == TEAM[i-1].AC && TEAM[i].tol_time == TEAM[i-1].tol_time)//解决同rank输出情况 { printf(" %-30s%-10d%d\n",TEAM[i].team_name.c_str(),TEAM[i].AC,TEAM[i].tol_time); } else printf("%-10d%-30s%-10d%d\n",rank,TEAM[i].team_name.c_str(),TEAM[i].AC,TEAM[i].tol_time); } } int main() { //freopen("in.txt","r",stdin); int N; int time,pro; string team,judge; map<string,int>m; team_sum = 0;//总队数初始0 cin>>N; while(cin>>time>>team>>pro>>judge) { int id;//队伍id if(m.find(team) == m.end()) { id = team_sum++; m[team] = id;//映射 TEAM[id].AC = TEAM[id].tol_time = 0; TEAM[id].team_name = team; memset(TEAM[id].problem,0,sizeof(TEAM[id].problem)); } else id = (*m.find(team)).second; if(judge == "AC" && TEAM[id].problem[pro] != 1) { TEAM[id].tol_time += time - TEAM[id].problem[pro]; TEAM[id].AC ++; TEAM[id].problem[pro] = 1;//表示已经AC } else { if(TEAM[id].problem[pro] == 1) continue; TEAM[id].problem[pro] -= 20; } } sort(TEAM,TEAM+team_sum); print(); return 0; }
zoj1444 Final Standings解题报告