网教14. 比赛计分问题

在 ACM/ICPC 地区赛中,参赛队可以直接提交题目答案,但若答案错误,则再次提交时最后的成绩会受到影响。比赛的测试系统对每次提交的程序进行评判,结果是 AC 或者某种错误,参赛队能看到这个结果。

为了奖励优秀的队伍同时确定进军世界总决赛的资格名单,当两个队伍做出的题目数量相同时,会按照其使用的时间来进行进一步的排名。时间有两个部分,第一是总的解题时间,二是惩罚时间。所谓惩罚时间是指提交程序未通过时被罚的时间,每一次未通过的提交,都会在最终用于排名的时间中增加 20 分钟。对于没解决的题目不计时。

你的程序将读入一张运行结果清单,然后打印出前三名的成绩。

输入

输入文件包含若干测试数据集。

每个测试数据由两个部分组成,第一部分包含了一个正整数,它表示参赛队伍的个数。接下来的几行是每次提交的结果。每行表示一次提交的结果,包括提交时间、队伍编号、问题编号和裁定结果。

当一行中提交时间一项为 0 时,则表示当前的数据集结束。当参赛队伍的个数为 0 时,则表示全部输入的结束。

每个测试集中队伍的个数不超过 100 个,提交的次数不超过 10000 次。

输出

针对每一组输入,输出前三名的比分,包括队号、做出题数、比赛用时、名次。在输出排名前,要输出“case n”,其中 n 表示当前是第几组输入。

假设:可能有好几队在同一名次。比如如果有几队都是第三名,则将他们全部输出;如果有两队是第二名,则没有第三名。当队伍名次相同时,按照队伍编号从小到大输出。

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 3↵
  2. 12 1 2 yes↵
  3. 14 3 2 no↵
  4. 25 3 1 yes↵
  5. 29 1 1 no↵
  6. 38 3 2 yes↵
  7. 39 2 1 no↵
  8. 45 1 1 no↵
  9. 0↵
  10. 0↵
以文本方式显示
  1. case 1:↵
  2. 3 2 83 1↵
  3. 1 1 12 2↵
  4. 2 0 0 3↵
1秒 1024KB 0
题解:
这个题不是很难,就是计数就行了。科普一个知识:ACM一般不会超过12道题,所以开记录这个的数组时开15一定就够用了。
一开始我的读入方法很麻烦,先读字符串,然后再从字符串里分割。后来发现可以直接读scanf("%d%d%d%s",&time,&team,&que,s);感觉发现了黑科技。。。
计分的时候是yes了之后才把计时和罚时都加上,而不是no的时候就加。一开始这里写错了,后来开一个15大小的数组记录,就行了。
有一个要注意的问题是,两个并列第一的话下一名就是第三了,好多同学在这里卡住。
AC代码:
#include<stdio.h>  
#include<string.h>  
#include<math.h>  
struct  node{  
    int a, b, c, d[15];  
}sco[105];//a存队伍号,b存总成绩,c存做出的题,d每个题的罚时  
  
char readin[10005][20];  
int main()  
{  
    int m, n;  
    n = 0;  
    while (1)  
    {  
        n++;  
        scanf("%d", &m);  
//      getchar();  
        if (m == 0)  
            break;  
        memset(readin, 0, sizeof(readin));  
        int j;  
        for (j = 1; j <= m; j++)  
        {  
            sco[j].a = j;  
            sco[j].b = 0;  
            sco[j].c = 0;  
            int k;  
            for (k = 0; k < 15; k++)  
                sco[j].d[k] = 0;  
        }  
        int i = 0;  
        while (1)  
        {  
            gets(readin[i]);  
            if (readin[i][0] == '0'&&readin[i][1] == '\0')  
                break;  
            int len,sco1=0, team=0, que=0;  
            len = strlen(readin[i]);  
            for (j = 0; j < len;j++)  
            if (readin[i][j] == ' ')  
                break;//现在j存的是空格  
            int t;  
            for (t = 0; t < j; t++)  
                sco1 += pow(10.0, j - 1 - t)*(readin[i][t]-'0');  
            for (t = j + 1; t < len;t++)  
            if (readin[i][t] == ' ')  
                break;//现在t存的是空格  
            for (j = j+1; j < t; j++)  
                team += pow(10.0, t - 1 - j)*(readin[i][j] - '0');  
            for (j = t + 1; j < len;j++)  
            if (readin[i][j] == ' ')  
                break;  
            for (t = t+1; t < j; t++)  
                que += pow(10.0, j - 1 - t)*(readin[i][t] - '0');  
              
            if (readin[i][j + 1] == 'y')  
            {  
                sco[team].b += sco1 + sco[team].d[que];  
                sco[team].c++;  
            }  
            else  
                sco[team].d[que] += 20;  
  
            i++;  
        }//字符串做法  
/*      int sco1 = 0, team = 0, que = 0; 
        char ac[5]; 
        scanf("%d", &sco1); 
        while (sco1 != 0) 
        { 
            scanf("%d%d%s", &team, &que, &ac); 
            if (ac[0] == 'y') 
            { 
                sco[team].b += sco1 + sco[team].d[que]; 
                sco[team].c++; 
            } 
            else 
                sco[team].d[que] += 20; 
            scanf("%d", &sco1); 
        }//数字做法*/  
        for (i = 1; i <= m;i++)  
        for (j = 1; j<=m - i;j++)  
        if (sco[j + 1].c>sco[j].c)  
        {  
            int tmp;  
            tmp = sco[j].a;  
            sco[j].a = sco[j + 1].a;  
            sco[j + 1].a = tmp;  
            tmp = sco[j].b;  
            sco[j].b = sco[j + 1].b;  
            sco[j + 1].b = tmp;  
            tmp = sco[j].c;  
            sco[j].c = sco[j + 1].c;  
            sco[j + 1].c = tmp;  
        }  
        else if (sco[j + 1].c == sco[j].c)  
        {  
            if (sco[j + 1].b < sco[j].b)  
            {  
                int tmp;  
                tmp = sco[j].a;  
                sco[j].a = sco[j + 1].a;  
                sco[j + 1].a = tmp;  
                tmp = sco[j].b;  
                sco[j].b = sco[j + 1].b;  
                sco[j + 1].b = tmp;  
                tmp = sco[j].c;  
                sco[j].c = sco[j + 1].c;  
                sco[j + 1].c = tmp;  
            }  
            else if (sco[j + 1].b == sco[j].b)  
            if (sco[j + 1].a<sco[j].a)  
            {  
                int tmp;  
                tmp = sco[j].a;  
                sco[j].a = sco[j + 1].a;  
                sco[j + 1].a = tmp;  
                tmp = sco[j].b;  
                sco[j].b = sco[j + 1].b;  
                sco[j + 1].b = tmp;  
                tmp = sco[j].c;  
                sco[j].c = sco[j + 1].c;  
                sco[j + 1].c = tmp;  
            }  
        }  
        printf("case %d:\n", n);  
        int tmp=1;  
        int maxe = 4;  
        if (m < 3)  
            maxe = m + 1;  
        for (i = 1; i < maxe; i++)  
        {  
            printf("%d %d %d %d\n", sco[i].a,sco[i].c,sco[i].b,tmp);  
            while (i < m&&sco[i].b == sco[i + 1].b && sco[i].c == sco[i + 1].c)  
            {  
                i++;  
                printf("%d %d %d %d\n", sco[i].a, sco[i].c, sco[i].b, tmp);  
            }  
            tmp = i+1;  
        }  
    }  
    return 0;  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值