C语言排序(4)___ACM contests

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


样例:

#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;
}

你可能感兴趣的:(C语言,ACM,快排)