P6675 [COCI2019-2020#2] ACM

· · 题解

题意及解析题目

输入数据共 1 + n 行。

第一行两个整数 nm,表示参赛队伍的个数和题目的个数。

接下来 n 行,每行的输入格式如下:

  1. 首先输入队伍名称;
  2. 接下来 m 个字符串,格式均为 SX/V,说明如下:
    • S 表示题目状态,共有三种字符:-+?- 表示该题目该团队未通过,+ 表示该题目该团队已通过,? 表示该题目最后一次提交时排行榜已冻结。
    • X 表示该题目该团队的提交次数。特别地,如果该题目该团队未提交,则 X 省略。
    • V 表示该题目该团队最后一次提交时比赛已经开始的时间,用 HH:MM:SS 表示,可能有前导零来补足。特别地,如该题目未通过,则整个 /V 部分省略。

最后一行按照前面的格式,输入 NijeZivotJedanACM 的最终成绩(即排行榜解冻后的成绩)

输出 NijeZivotJedanACM 可能会处在的最差排名。

贪心与排序

要使 NijeZivotJedanACM 排名靠后,则其余组的排名要尽可能靠前,即将其余组的 ? 视为 +,将 NijeZivotJedanACM 的 ? 视为 -

对于此题,使用结构体进行排序名次,手写 cmp 函数进行对比判断即可。

对于所耗时间,需要进行统一,这里我用了统一成秒数,(因为大单位化小单位好算)最后如果通过了这一题,就加上罚时的秒数,判断即可。

奇奇怪怪的题意

ACM 赛制是每提交错误一次就罚时,但罚时的结果是只有你做出来这道题之后才会统计上去,也就是说,只要你一直没做出来这道题,就等于没有罚时。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e3+5,rate=1200;//rate代表小时化为分钟的进率 
int n,m,down;
int intt(char x){//巧用ASCII码进行char类转int类 
    return x-'0';
}
struct node{
    string name;
    int AC,miao;
}a[MAXN];
char ch[MAXN];
bool cmp(node x,node y){
    if(x.AC==y.AC){//正确数相等 
        if(x.miao==y.miao) return x.name<y.name;//时间相等就比较名字字典序 
        return x.miao<y.miao;//否则比较时间 
    }
    return x.AC>y.AC;//通用的判断 
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n+1;i++){
        cin>>a[i].name;
        if(i!=n+1&&a[i].name=="NijeZivotJedanACM") down=i;//如果检测到了NijeZivotJedanACM的做题记录,就记录当前下标 
        for(int j=1;j<=m;j++){
            cin>>ch+1;
            if(ch[1]=='-') continue;//没通过就删了吧 
            else{
                a[i].miao+=3600*intt(ch[5])+60*(10*intt(ch[7])+ch[8])+10*intt(ch[10])+intt(ch[11]);
                a[i].miao+=(intt(ch[2])-1)*rate;
                a[i].AC++; 
            }
        }
    }
    a[down]=a[n+1];//把最后一位的数据全部塞进NijeZivotJedanACM的记录中 
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        if(a[i].name=="NijeZivotJedanACM"){
            printf("%d",i);
            return 0;
        }
    }
    return 0;
}