南邮 OJ 1983 比赛成绩排序问题II

该博客讨论了南邮OJ平台上的1983题——比赛成绩排序问题II。博客解释了比赛的规则,即通过两两PK赛来决定排名,并通过示例解释如何根据胜负关系确定排名是否确定。博主给出了输入输出格式,并提供了样例输入和对应的正确输出。此问题旨在测试参赛者处理排序和冲突检查的能力。
摘要由CSDN通过智能技术生成

比赛成绩排序问题II

时间限制(普通/Java) :  2000 MS/ 6000 MS          运行内存限制 : 65536 KByte
总提交 : 218            测试通过 : 43 

比赛描述

2013“华为杯”南京邮电大学大学生团体歌唱大赛比赛形式为:大赛分为多轮,每一轮随机选择参赛团体进行两两PK赛。当根据多轮多场的PK赛成绩能够确定排名次序时,大赛结束。

我们将问题进行简化,从1开始按递增顺序给每一个参赛团体分配一个整数编号,每个参赛团体在比赛期间表现出的歌唱水平各不相同且稳定不变,每场PK赛成绩必定胜负。给定已记录的多场PK赛成绩,请你根据胜负关系确定大赛是否应该结束,并且能够排除记录出现错误的情形。

举一个例子,共有三个参赛团体参加大赛,如果参赛团体1在PK赛中胜参赛团体3、参赛团体2在PK赛中胜参赛团体1,则可知参赛团体2的成绩比参赛团体3的成绩排名高,也说明参赛团体2的歌唱水平一定高于参赛团体3的歌唱水平;如果参赛团体1在PK赛中胜参赛团体2、参赛团体2在PK赛中胜参赛团体3、参赛团体3在PK赛中胜参赛团体1,则出现这种情形说明存在明显的记录错误。



输入

输入包括多个测试用例。

每个测试用例包括C+1行,第1行给出参赛团体总数M、已知PK赛成绩的场次数C;接下来有C行,每一行先后给出两个参赛团体编号pq,表示编号为p的参赛团体在PK赛中胜编号为q的参赛团体;这里1≤M≤10001≤C≤5000001≤p≤M1≤q≤Mp≠q

最后一行为“0 0”,表示输入结束,这一行无需处理。

输出

针对问题输入中的每个测试用例,输出一行字符串,具体规定如下:

l  根据已记录的PK赛成绩能够确定排名次序时,则输出字符串Competition over

l  根据已记录的PK赛成绩还不能确定排名次序时,则输出字符串Competition continue

l  根据已记录的PK赛成绩不可能确定排名次序时,则输出字符串Wrong Results

样例输入

4 3
4 3
3 2
2 1
4 3
4 3
2 3
1 4
4 3
4 3
1 4
3 1
0 0

样例输出

Competition over
Competition continue
Wrong Results

提示

本题对只限于修读任选课同学不作要求,有志于参加2014年南邮ACM竞赛集训队的同学不妨试试。

题目来源

SED





/* 398MS
#include<iostream>

#include<iostream>
using namespace std;
struct node
{
    int k;
    struct node *next;
    node()
    {
        k=0;
        next=NULL;
    }
}*A,*p;
int *R,*T;
int M,C;
int topsort(struct node *A)
{
    bool flag=false;
    struct node *p,*q;
    int temp_q=-1;
    int num=0;
    while(R[0]!=-1)
    {
        temp_q=-1;
        if(R[R[0]]!=-1)
        {
            flag=true;
        }
        for(int i=R[0]; i!=-1;)
        {
            p=A[i].next;
            while(p)
            {
                R[p->k]--;
                if(R[p->k]==0)
                {
                    R[p->k]=temp_q;
                    temp_q=p->k;
                }
                p=p->next;

            }
            R[0]=R[i];
            num++;
            i=R[i];
        }
        R[0]=temp_q;
    }
    if(num==M)
    {
        if(!flag)
            return 0;
        else
            return -1;
    }

    else
    {
        return 1;
    }
}

int main()
{
    int a,b;
//    freopen("aa.txt","r",stdin);
    while(scanf("%d%d",&M,&C)!=0)
    {
        if(!M|!C)
            break;
        A=new struct node[M+1];
        R=new int[M+1];
        T=new int[M+1];
        for(int i=0; i<=M; i++)
        {
            R[i]=0;
            T[i]=0;
        }
        for(int i=0; i<C; i++)
        {
            scanf("%d%d",&a,&b);
            p=new node;
            p->k=b;
            p->next=A[a].next;
            A[a].next=p;
            R[b]++;
        }
        R[0]=-1;
        for(int i=1; i<=M; i++)
        {
            if(R[i]==0)
            {
                R[i]=R[0];
                R[0]=i;
            }

        }
        int result=topsort(A);
        if(result==0)
            printf("Competition over\n");

        else if(result==-1)
            printf("Competition continue\n");

        else
            printf("Wrong Results\n");

    }
    return 0;
}
*/

/* Wrong Answer at Test 1
#include<iostream>

#define MAX_N 1001
bool map[MAX_N][MAX_N];
int in_degree[MAX_N];
int n;

// 返回 1 : 成功唯一排序
//      2 : 排序不唯一
//      3 : 有环,无法排序
int top_sort(){
	int count=0;		//0入度的个数
	int num=0;			//已经排序出来的额个数
	int i,k,no_deg0;	//入度为0的编号
	for(i=1;i<=n;i++){
		if(in_degree[i]==0){
			count++;
			no_deg0 = i;
		}
	}
	while(count==1){
		num++;
		count--;
		k = no_deg0;
		for(i=1;i<=n;i++){
			if(map[k][i]){
				if(--in_degree[i]==0){
					count++;
					no_deg0 = i;
				}
			}
		}
	}
	if(num==n){
		return 1;
	}else if(count>1){
		return 2;
	}else{
		return 3;
	}
}

int main(){
	int c,p,q;
	while(scanf("%d%d",&n,&c)==2 && (n||c)){
		if(c+1<n){
			printf("Competition continue\n");
			while(c--){
				scanf("%*d%*d");
			}
			continue;
		}
		memset(map,0,sizeof(map));
		memset(in_degree,0,sizeof(in_degree));
		while(c--){
			scanf("%d%d",&p,&q);
			map[p][q] = 1;
			in_degree[q]++;
		}
		c = top_sort();
		if(c==1){
			printf("Competition over\n");
		}else if(c==2){
			printf("Competition continue\n");
		}else{
			printf("Wrong Results\n");
		}
	}
}
*/



/* 328MS
#include<iostream>
#include<vector>
using namespace std;

#define MAX_N 1001
bool map[MAX_N][MAX_N];
int in_degree[MAX_N];
int n;

// 返回 1 : 成功唯一排序
//      2 : 排序不唯一
//      3 : 有环,无法排序
int top_sort(){
	int num=0;			//已经排序出来的额个数
	int i,k;
	vector<int> vi;		//入度为0的编号
	bool flag;
	for(i=1;i<=n;i++){
		if(in_degree[i]==0){
			vi.push_back(i);
		}
	}
	flag = 0;
	while(vi.size()){
		if(vi.size()>1){
			flag = 1;
		}
		num++;
		k = vi.back();
		vi.pop_back();
		for(i=1;i<=n;i++){
			if(map[k][i]){
				if(--in_degree[i]==0){
					vi.push_back(i);
				}
			}
		}
	}
	if(num==n){
		if(flag){
			return 2;	
		}else{
			return 1;
		}
	}else{				//排不到最后,同时出现入度大于1的情况,算情况3
		return 3;
	}
}

int main(){
//	freopen("test.txt","r",stdin);
	int c,p,q;
	while(scanf("%d%d",&n,&c)==2 && (n||c)){
//		if(c+1<n){
//			printf("Competition continue\n");
//			while(c--){
//				scanf("%*d%*d");
//			}
//			continue;
//		}
		memset(map,0,sizeof(map));
		memset(in_degree,0,sizeof(in_degree));
		while(c--){
			scanf("%d%d",&p,&q);
			map[p][q] = 1;
			in_degree[q]++;
		}
		c = top_sort();
		if(c==1){
			printf("Competition over\n");
		}else if(c==2){
			printf("Competition continue\n");
		}else{
			printf("Wrong Results\n");
		}
	}
}
*/

/* 320MS
#include<iostream>

#define MAX_N 1001
bool map[MAX_N][MAX_N];
int in_degree[MAX_N];
int zero_degree[MAX_N];
int n;

// 返回 1 : 成功唯一排序
//      2 : 排序不唯一
//      3 : 有环,无法排序
int top_sort(){
	int num=0;			//已经排序出来的额个数
	int i,k;
	bool flag;
	for(i=1;i<=n;i++){
		if(in_degree[i]==0){
			zero_degree[++zero_degree[0]] = i;
		}
	}
	flag = 0;
	while(zero_degree[0]){
		if(zero_degree[0]>1){
			flag = 1;
		}
		num++;
		k = zero_degree[zero_degree[0]];
		zero_degree[0]--;
		for(i=1;i<=n;i++){
			if(map[k][i]){
				if(--in_degree[i]==0){
					zero_degree[++zero_degree[0]] = i;
				}
			}
		}
	}
	if(num==n){
		if(flag){
			return 2;	
		}else{
			return 1;
		}
	}else{
		return 3;
	}
}

int main(){
//	freopen("test.txt","r",stdin);
	int c,p,q;
	while(scanf("%d%d",&n,&c)==2 && (n||c)){
//		if(c+1<n){
//			printf("Competition continue\n");
//			while(c--){
//				scanf("%*d%*d");
//			}
//			continue;
//		}
		memset(map,0,sizeof(map));
		memset(in_degree,0,sizeof(in_degree));
		memset(zero_degree,0,sizeof(zero_degree));
		while(c--){
			scanf("%d%d",&p,&q);
			map[p][q] = 1;
			in_degree[q]++;
		}
		c = top_sort();
		if(c==1){
			printf("Competition over\n");
		}else if(c==2){
			printf("Competition continue\n");
		}else{
			printf("Wrong Results\n");
		}
	}
}
*/

#include<iostream>

#define MAX_N 1001
int map[MAX_N][MAX_N];	//改用map存储邻居节点,反而时间更长了,变为429MS,可能因为int存取较慢,也可能数组偏移地址的运算耗时较多
int in_degree[MAX_N];
int zero_degree[MAX_N];
int n;

// 返回 1 : 成功唯一排序
//      2 : 排序不唯一
//      3 : 有环,无法排序
int top_sort(){
	int num=0;			//已经排序出来的额个数
	int i,k;
	bool flag;
	for(i=1;i<=n;i++){
		if(in_degree[i]==0){
			zero_degree[++zero_degree[0]] = i;
		}
	}
	flag = 0;
	while(zero_degree[0]){
		if(zero_degree[0]>1){
			flag = 1;
		}
		num++;
		k = zero_degree[zero_degree[0]];
		zero_degree[0]--;
		int temp = map[k][0];
		for(i=1;i<=temp;i++){
			if(--in_degree[map[k][i]]==0){
				zero_degree[++zero_degree[0]] = map[k][i];
			}
		}
	}
	if(num==n){
		if(flag){
			return 2;	
		}else{
			return 1;
		}
	}else{
		return 3;
	}
}

int main(){
//	freopen("test.txt","r",stdin);
	int c,p,q;
	while(scanf("%d%d",&n,&c)==2 && (n||c)){
		if(c+1<n){
			printf("Competition continue\n");
			while(c--){
				scanf("%*d%*d");
			}
			continue;
		}
		memset(map,0,sizeof(map));
		memset(in_degree,0,sizeof(in_degree));
		memset(zero_degree,0,sizeof(zero_degree));
		while(c--){
			scanf("%d%d",&p,&q);
			map[p][++map[p][0]] = q;
			in_degree[q]++;
		}
		c = top_sort();
		if(c==1){
			printf("Competition over\n");
		}else if(c==2){
			printf("Competition continue\n");
		}else{
			printf("Wrong Results\n");
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在这个题目中,要求编写一个程序,根据输入的学生信息和成绩,对指定科目的成绩进行排序,并输出排名结果。首先需要定义一个结构体来存储学生信息,包括学生姓名和对应科目的成绩。然后通过输入的学生信息,将其存储到结构体数组中。接着根据输入的科目,对结构体数组进行排序,可以使用冒泡排序、快速排序等方法。最后将排序后的结果输出,即可完成题目要求。 首先,我们可以定义一个包含学生姓名和对应科目成绩的结构体,如下所示: ```c typedef struct Student { char name[20]; int score; } Student; ``` 然后,在主函数中,首先输入学生的总数n和指定科目的名称,然后根据n创建对应数量的结构体数组,并输入每个学生的姓名和指定科目成绩。接着可以使用冒泡排序对结构体数组按照指定科目成绩进行排序排序完成后,输出排名结果即可。 实现伪代码如下所示: ```c #include <stdio.h> int main() { int n; char subject[20]; scanf("%d %s", &n, subject); Student students[n]; for (int i = 0; i < n; i++) { scanf("%s %d", students[i].name, &students[i].score); } // 冒泡排序 for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (students[j].score < students[j + 1].score) { Student temp = students[j]; students[j] = students[j + 1]; students[j + 1] = temp; } } } // 输出排名结果 for (int i = 0; i < n; i++) { printf("%s %d\n", students[i].name, students[i].score); } return 0; } ``` 通过上述方法,可以对输入的学生信息和成绩进行排序,得出指定科目的排名结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值