首页 > 代码库 > zoj1444 Final Standings解题报告

zoj1444 Final Standings解题报告

题目大意:本题是模拟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;
}