Time Limit: 1000MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
3 3 1 2 3000 0 1 2 3100 1 2 1 4200 1
Sample Output
2 1 3
Source
【题目来源】
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; }