HUT 排序训练赛 C - ACM Rank Table

Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

[]   [Go Back]   [Status]  

Description

ACM contests, like the one you are participating in, are hosted by the special software. That software, among other functions, preforms a job of accepting and evaluating teams' solutions (runs), and displaying results in a rank table. The scoring rules are as follows:
  1. Each run is either accepted or rejected.
  2. The problem is considered solved by the team, if one of the runs submitted for it is accepted.
  3. The time consumed for a solved problem is the time elapsed from the beginning of the contest to the submission of the first accepted run for this problem (in minutes) plus 20 minutes for every other run for this problem before the accepted one. For an unsolved problem consumed time is not computed.
  4. The total time is the sum of the time consumed for each problem solved.
  5. Teams are ranked according to the number of solved problems. Teams that solve the same number of problems are ranked by the least total time.
  6. While the time shown is in minutes, the actual time is measured to the precision of 1 second, and the the seconds are taken into account when ranking teams.
  7. Teams with equal rank according to the above rules must be sorted by increasing team number.

Your task is, given the list of N runs with submission time and result of each run, compute the rank table for C teams.

Input

Input contains integer numbers C N, followed by N quartets of integes ci pi ti ri, where ci -- team number, pi -- problem number, ti -- submission time in seconds, ri -- 1, if the run was accepted, 0 otherwise.
1 ≤ C, N ≤ 1000, 1 ≤ ci ≤ C, 1 ≤ pi ≤ 20, 1 ≤ ti ≤ 36000.

Output

Output must contain C integers -- team numbers sorted by rank.

Sample Input

3 3
1 2 3000 0
1 2 3100 1
2 1 4200 1

Sample Output

2 1 3

Source

Northeastern Europe 2004, Far-Eastern Subregion

【题目来源】

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41455#problem/C

【题目大意】

这题主要是涉及到ACM比赛的规则,只要知道ACM比赛规则的人理解这一题的题意就不难,首先输入C和N,C代表的是测试数据的数量,N代表的是每个测试数据的提交记录条数,

然后是输入N条提交记录,每条提交记录包括四个数,分别是队的编号、题目编号、提交时间、评测结果(1-A 0-w),让我们根据比赛规则来排名然后输出队的编号。

 

很打击我的一题,初读题目感觉很简单,然后就开始写,结果越写越觉得写不下去,主要是有很多的细节要去处理。。。然后又重新看题,将要注意的点列了一个清单。。。然后才开始敲代码,很神奇竟然一遍过了。。。

这你就将这一题要注意的点列出来,这几点没问题基本就能过了:

1、首先要注意的是输入的提交记录并不是按照时间顺序来排列的,所以第一步就得按照时间来排序(这样有一个好处就是在处理单条记录的时候按照时间去处理,就可以知道他是不是第一次提交,从而判断是否加罚时)

2、输入数据可能有提交AC后再次提交的,程序要能识别并加以忽略。(这就是去重的问题)

3、没做对的题的时间不能加在总罚时里面(加时间之前用一个判断)

总之,只要把每条京密路按照时间来排一下序就可以大大减少出错的几率。

【解题思路】

首先用一个结构体来存储每一条输入的记录。struct node{  int ci,pi,ti,ri;}  lnode[1008];

然后再用一个结构体来存储最终的评判结果(包括AC的题数,罚时,AC的题号,wrong的题号)struct score{    int time;  int num;    int wpro[25];    int index;   int prob[25];}    stu[1008];

然后就开始模拟。

值得注意的是,这题要排两次序(第一次是时间,第二次是成绩),所以得写两个CMP函数,而且涉及到结构体的排序(百度一下)。

基本就是这样吧。下面是我的AC代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<algorithm>
using namespace std;
struct list
{
    int sum1,sum2,num,p1[22],p2[22];
} a[1002];
struct in
{
   int c,p,t,r;
} b[1002];
int cmp1(in x, in y)
{
    return x.t<y.t;
}
int cmp2(list x,list y)
{
    if(x.sum1==y.sum1 && x.sum2==y.sum2) return x.num<y.num;
    else if(x.sum1==y.sum1) return x.sum2<y.sum2;
    return x.sum1>y.sum1;
}

int main()
{
    int m,n;
    int c,p,t,r,i;
    scanf("%d%d",&m,&n);
    memset(a,0,sizeof(a));
    for(i=1;i<=m;i++) a[i].num=i;
    for(i=1;i<=n;i++) scanf("%d%d%d%d",&b[i].c,&b[i].p,&b[i].t,&b[i].r);
    sort(b+1,b+1+n,cmp1);
    for(i=1;i<=n;i++)
    {
     c=b[i].c; p=b[i].p; t=b[i].t; r=b[i].r;
     if(r==0) a[c].p1[p]+=1200;
     if(r==1 && a[c].p2[p]==0)
      {
       a[c].sum1+=1;
       a[c].sum2+=(a[c].p1[p]+t);
       a[c].p2[p]=1;
      }
    }
    sort(a+1,a+1+m,cmp2);
    for(i=1;i<m;i++) printf("%d ",a[i].num); printf("%d\n",a[m].num);
    return 0;
}

 

或许下面这个跟容易理解(转):

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct score{
    int time;//罚时
    int num;//AC的题数
    int wpro[25];//错的题数
    int index;// 编号
    int prob[25];//题目编号
}stu[1008];
struct node{
    int ci,pi,ti,ri;
}lnode[1008];//提交记录
int cmp1(const void *a,const void *b)//时间排序
{
    struct node *c,*d;
    c=(struct node *)a;
    d=(struct node *)b;
    if(c->ti!=d->ti)
    return c->ti-d->ti;
    else return c->ri-d->ri;//时间相同,AC的在前
}
int cmp2(const void *a,const void *b)//成绩排序
{
    struct score *c,*d;
    c=(struct score *)a;
    d=(struct score *)b;
    if(c->num!=d->num)//先按AC的题数来排
        return d->num-c->num;
    else if(c->time!=d->time)//按罚时来排
    return c->time-d->time;
    else return c->index-d->index;//按队的编号来排
}
int main()
{
    int i,m,n,j,max;
    memset(stu,0,sizeof(stu));//置零
    scanf("%d%d",&m,&n);
    for(i=0;i<m;i++)
        stu[i].index=i;//编号
    max=0;
    for(i=0;i<n;i++)
    {
        scanf("%d%d%d%d",&lnode[i].ci,&lnode[i].pi,&lnode[i].ti,&lnode[i].ri);
        if(max<lnode[i].pi)max=lnode[i].pi;//出现的最大题数
    }
    qsort(lnode,n,sizeof(lnode[0]),cmp1);
    for(i=0;i<n;i++)
    {
        if(lnode[i].ri==0)//提交了,错误
        {
            if(stu[lnode[i].ci-1].prob[lnode[i].pi]!=1)//并且判断这题AC了
            stu[lnode[i].ci-1].wpro[lnode[i].pi]++;
        }
        else{
            if(stu[lnode[i].ci-1].prob[lnode[i].pi]!=1){
            stu[lnode[i].ci-1].time+=lnode[i].ti;
            stu[lnode[i].ci-1].prob[lnode[i].pi]=1;
            stu[lnode[i].ci-1].num++;}
        }
    }
    for(i=0;i<m;i++)
        for(j=1;j<=max;j++)
            if(stu[i].prob[j]==1)
                stu[i].time+=1200*stu[i].wpro[j];
    qsort(stu,m,sizeof(stu[0]),cmp2);
    for(i=0;i<m-1;i++)
        printf("%d ",stu[i].index+1);
    printf("%d\n",stu[m-1].index+1);
    return 0;
}

 

你可能感兴趣的:(table)