链接:https://ac.nowcoder.com/acm/contest/327/B
来源:牛客网
题目描述
众所周知,处女座经常通过打cf来调节自己的心情。今天处女座又参加了一场cf的比赛,他知道了所有的提交记录,他想知道自己的得分和排在第几名。你知道处女座的cf账号是cnz
Codeforces规则如下:
1. 比赛一共2小时
2. 比赛有5题,A题500分,B题1000分,C题1500分,D题2000分,E题2500分。
3. 得分规则如下:
在第0分钟完成某一题可以得到全部的分数,每过一分钟每题的分值会衰减1/250,比如在第3分钟完成A题,能够得到500-2*3=494分
4. 如果一道题是的返回结果WA或者TLE被称为错误的提交,CE视为无效的提交,AC,WA和TLE 都视为有效的提交。如果一道题你最后通过了,你会得到这道题衰减之后的分值再减去你错误提交次数*50,就是每次错误的提交会有50分的罚时。
5. 如果你通过了一道题,你的得分不会低于该题分值的30%。比如你在第50分钟通过了A,你有7次错误的提交,你的得分为max(500*0.3,500-2*50(得分衰减)-7*50(错误提交的罚时))=150分。
6. 由于hack机制的存在,你每进行一次提交,对于这一题之前的有效提交(AC,WA,TLE)都视为错误的提交。
7. 一个人只有提交(AC,WA,TLE,CE)过代码,才被视为参加比赛。
处女座又了解到一些信息:
本场比赛没有任何选手hack别人,并且没有任何的提交fst(即只要是某题的最后一次提交通过,就视为通过这道题)
输入描述:
第一行两个整数n和m,n为报名比赛的人数,m为提交的个数
接下来n行,每行一个字符串,表示报名比赛的人的昵称。(字符串只包含小写字母,且长度小于20)
接下来m行,每行的格式为Time,Submiter,Problem,Verdict。
Time为提交的时间,是1到120中的一个正整数(包含1和120),保证Time按顺序给出
Submiter为提交者昵称
Problem为题目名称,是’A’,’B’,’C’,’D’,’E’中的一个字母。
Verdict为返回的结果,为”AC”,”WA”,”TLE”,”CE”中的一个。
2<=n<=500
1<=m<=10000
输出描述:
如果处女座参加了比赛,输出两行:
第一行为处女座的得分
第二行格式x/y,其中x为处女座的排名,y为参加比赛的总人数。如果分数相同那么排名并列。
如果处女座没有参加比赛,输出”-1”
示例1
输入
3 7 cnz cuber moon 3 cnz A AC 5 cuber A AC 6 cnz B CE 10 cuber C AC 20 cnz B AC 30 cuber D TLE 100 cnz E AC
输出
2914 1/2
题目的坑:(能用人话讲清楚的,非要用鬼话)
1.以最后一次提交作为结果,比如ac之后又wa,当作wa
2.提交ce是无效提交,不扣分,但是可以认为参加了比赛
3.ac之后又ac,上次的ac作为错误提交,相当于wa
4.关系错综复杂,要正确处理好各自的关系,用映射解决提交过程中选手的编号
#include<stdio.h> #include<iostream> #include<algorithm> #include<cstring> #include<math.h> #include<set> #include<string> #include<sstream> #include<map> #define ll long long #define inf 0x3f3f3f3f using namespace std; map<string,int>mp;//参赛选手对应编号以方便查找数组下标 int ans[505];//最终分数 int ac[505][10]; int wa[505][10]; bool flag[505];//是否参赛 int main() { memset(ans,0,sizeof(ans)); memset(ac,-1,sizeof(ac));//初始化没有ac的状态为-1,如果ac则改为ac的时间 memset(wa,0,sizeof(wa)); memset(flag,false,sizeof(flag)); int n,m; string s; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { cin>>s; mp[s]=i; } int t; char p; string v; for(int i=1;i<=m;i++) { cin>>t>>s>>p>>v; flag[ mp[s] ]=true;//确定为参赛 if(v[0]!='A')//wa { if(ac[mp[s]][p-'A']!=-1) //ac过,犯贱让它wa了 { ac[mp[s]][p-'A']=-1;//重新置为没有ac wa[mp[s]][p-'A']++;//wa次数+1,上次ac当作wa处理, } wa[mp[s]][p-'A']++;//本次又是一发wa } else //ac { if(ac[mp[s]][p-'A']!=-1)//ac后又ac { wa[mp[s]][p-'A']++;//上一发ac当作wa,wa+1 ac[mp[s]][p-'A']=t;//更新ac时间 } else//没ac过 { ac[mp[s]][p-'A']=t; } } if(v[0]=='C')//CE是无效提交,前面把它当作有效提交wa处理了 wa[mp[s]][p-'A']--; } int num=0; for(int i=1;i<=n;i++) { if(flag[i]) { num++;//统计参赛人数 for(int j=0;j<=4;j++)//遍历五道题统计分数 { if(ac[i][j]!=-1)//ac的题目才算分 { int group=500+j*500;//本题分数 int minn=group*0.3;//本题至少得分,max函数里不允许用group*0.3 int tg=ac[i][j]*(group/250);//因时间问题扣分 int wag=wa[i][j]*50;//因wa扣分 ans[i]=ans[i]+max(minn,group-tg-wag);//累加参赛选手的总分 } } } } if(!flag[mp["cnz"]]) printf("-1 ");//处女座没参赛输出一行就好 else { printf("%d ",ans[mp["cnz"]]); int rank=1;//初始化排位为1 for(int i=1;i<=n;i++) { //printf("ans[%d]=%d ",i,ans[i]); if(ans[i]>ans[mp["cnz"]]) rank++;//不要去统计排第几,有一人比他高,排名就往后掉 } printf("%d/%d",rank,num); } return 0; }