Description
Input
Output
Sample Input
3 3
1 2 3000 0
1 2 3100 1
2 1 4200 1
Sample Output
2 1 3
样例:
#include <stdio.h> #include <string.h> struct ACM //定义参赛队伍信息 { int num; //队伍ac数量 int now_time; //总共罚时 int times[30]; //每道题的错误次数 int team_num; //队伍编号 int book_pro[30]; //每道题的ac情况 }acm[1005]; int compare(struct ACM a,struct ACM b) //定义队伍的比较函数 { int book=0; if(a.num<b.num) //1.队伍ac数量排序 book=1; else if(a.num==b.num && a.now_time>b.now_time) //2.队伍罚时排序 book=1; else if(a.num==b.num && a.now_time==b.now_time&&a.team_num>b.team_num) //3.当罚时和ac数量一样的时候,队伍编号升序 book=1; return book; } void quicksort(int left,int right) //定义队伍排序的快排函数 { int i,j; struct ACM m,step; i=left,j=right,step=acm[left]; if(i>j) return; while(i!=j) { while(i<j&&(compare(acm[j],step)==1)) j--; while(i<j&&(compare(acm[i],step)==0)) i++; if(i<j) { m=acm[i]; acm[i]=acm[j]; acm[j]=m; } } acm[left]=acm[i],acm[i]=step; quicksort(left,i-1); quicksort(i+1,right); } struct XX //定义提交题目消息的结构体 { int team_num; int pro_num; int time; int book; }xx[1001]; void sort(int left,int right) //定义消息排序的快排函数 { int i,j; struct XX m,step; i=left,j=right,step=xx[left]; if(i>j) return; while(i!=j) { while(i<j&&xx[j].time>=step.time) j--; while(i<j&&xx[i].time<=step.time) i++; if(i<j) { m=xx[i]; xx[i]=xx[j]; xx[j]=m; } } xx[left]=xx[i],xx[i]=step; sort(left,i-1); sort(i+1,right); } int main() { int i,j,n,m; while(scanf("%d%d",&m,&n)!=EOF) //多组输入.m是队伍数,n是消息个数. { for(i=1;i<=m;i++) //重置m个队伍的信息,置为0. { acm[i].num=acm[i].now_time=0; acm[i].team_num=i; memset(acm[i].times,0,sizeof(acm[i].times)); memset(acm[i].book_pro,0,sizeof(acm[i].book_pro)); } for(i=0;i<n;i++) //存储n条题目提交信息 scanf("%d%d%d%d",&xx[i].team_num,&xx[i].pro_num,&xx[i].time,&xx[i].book); sort(0,n-1); //信息排序 for(i=0;i<n;i++) //读取并处理题目提交信息 { if(acm[xx[i].team_num].book_pro[xx[i].pro_num]==0) //如果这个队伍这个题目没有ac { if(xx[i].book==1) //如果这次提交消息的判断是ac { acm[xx[i].team_num].num++; //队伍ac数量加1 acm[xx[i].team_num].now_time+=xx[i].time+1200*acm[xx[i].team_num].times[xx[i].pro_num];//总罚时加上本题提交时间以及本题错误的罚时. acm[xx[i].team_num].book_pro[xx[i].pro_num]=1; //把这个队伍这道题令为已ac. } else //如果这次提交的判断没有ac. acm[xx[i].team_num].times[xx[i].pro_num]++; //那么这个队伍这道题的错误次数加1. } } quicksort(1,m); //调用函数对队伍进行排序 printf("%d",acm[1].team_num); //输出. for(i=2;i<=m;i++) printf(" %d",acm[i].team_num); printf("\n"); } return 0; }
对于每组数据,先输入两个整数分别表示参赛队伍数m以及提交题目消息数n
接下来的n排消息,每排有4个整数分别表示队伍编号,题目编号,提交时间,是否ac
然后对所有的队伍按照成绩排序.
这道题主要有这几个坑点.
1.输入的消息并非都是按照时间先后给的,所以要存储消息后先排序再处理.
2.对于该队伍已经ac的题目再次提交无论是否ac都不影响罚时、错误次数和ac数量.
3.对队伍进行排序的时候,如果出现罚时和ac数量都一样的,按照队伍序号升序排列.
注意:
定义结构体的时候里面数组不要开的过大,否则在每次重置初始值的时候遍历耗时太大,容易超时.
学长代码(主要思路一样.但学长使用了c++带的sort函数,缩短了代码长度):
#include<algorithm> #include<stdio.h> #include<string.h> using namespace std; struct sub{ int ci,pi,ti,ri; }s[1100]; struct team{ int id; int num; int tal_time; int times[30]; int ac[30]; }t[1100]; bool cmp1(sub a,sub b){ return a.ti<b.ti; } bool cmp2(team a,team b){ if(a.num!=b.num) return a.num>b.num; if(a.tal_time!=b.tal_time) return a.tal_time<b.tal_time; return a.id<b.id; } int main(){ int c,n; int i,j; while(scanf("%d%d",&c,&n)!=EOF){ for(i=1;i<=c;++i){ t[i].id=i; t[i].tal_time=0; t[i].num=0; memset(t[i].times,0,sizeof(t[i].times)); memset(t[i].ac,0,sizeof(t[i].ac)); } for(i=0;i<n;++i){ scanf("%d%d%d%d",&s[i].ci,&s[i].pi,&s[i].ti,&s[i].ri); } sort(s,s+n,cmp1); for(i=0;i<n;++i){ if(!(t[s[i].ci].ac[s[i].pi])){ if(!s[i].ri){ t[s[i].ci].times[s[i].pi]++; }else{ t[s[i].ci].tal_time+=s[i].ti+t[s[i].ci].times[s[i].pi]*20*60; t[s[i].ci].ac[s[i].pi]=1; t[s[i].ci].num++; } } } sort(t+1,t+c+1,cmp2); for(i=1;i<=c;++i){ if(i!=1) printf(" "); printf("%d",t[i].id); } printf("\n"); } return 0; }