题很水,数据注意一下四点即可:
1.有些team会在一道题AC了之后还提交,这个时候只需要算第一次ac的时间以及这之前的wa,之后的全部忽略。
2.如果一道题没有ac,那么在计算时间时不应该加上它的wa带来的惩罚。
3.先按做题最多的排,如相等,再按提交时间最少的排,如相等,再按队号最小的排。
4.给的数据,提交的时间不是按顺序排的。
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int maxn=1010; int C,N; int c,p,t,r; int res[maxn][maxn]; //res[c][p]=1表示队伍c解决了第p题,=0则未AC。 //存储提交的信息 struct Submit{ int team,pro,time,result; //队伍号,题号,提交时间,提交结果 void init(int c,int p,int t,int r){ team=c; pro=p; time=t; result=r; } //按提交时间从小到大排序,如果时间一样,AC的排在前面 bool operator<(const Submit tmp)const{ if(time==tmp.time) return result>tmp.result; return time<tmp.time; } }sub[maxn]; //队伍信息 struct Team{ int time,idx,wa[21],num; //总时间,队伍号,各题号WA的次数,AC的题数 void init(int i,int n,int t){ idx=i; num=n; time=t; memset(wa,0,sizeof(wa)); } //按AC的题数从大到小排序,如果相同则按时间从小到大排序,如果时间也相同,队伍号小的在前面 bool operator<(const Team tmp)const{ if(num==tmp.num){ if(time==tmp.time) return idx<tmp.idx; else return time<tmp.time; } return num>tmp.num; } }team[maxn]; int main() { memset(res,0,sizeof(res)); scanf("%d%d",&C,&N); for(int i=1;i<=C;i++){ team[i].init(i,0,0); } for(int i=0;i<N;i++){ scanf("%d%d%d%d",&c,&p,&t,&r); sub[i].init(c,p,t,r); } sort(sub,sub+N); for(int i=0;i<N;i++){ c=sub[i].team; p=sub[i].pro; t=sub[i].time; r=sub[i].result; if(r==0 && !res[c][p]){ team[c].wa[p]++; } else{ if(!res[c][p]){ team[c].time+=t; res[c][p]=1; team[c].num++; } } } for(int i=1;i<=C;i++){ for(int j=1;j<=20;j++){ //题目AC了,才加上相应的罚时 if(res[i][j]){ team[i].time+=team[i].wa[j]*20*60; } } } sort(team+1,team+C+1); for(int i=1;i<=C;i++){ if(i==1) printf("%d",team[i].idx); else printf(" %d",team[i].idx); } return 0; }