zl程序教程

您现在的位置是:首页 >  其它

当前栏目

中山加机试之四天速成篇之“确定比赛名次”

确定 比赛 速成
2023-09-14 09:14:59 时间

记住几个关键知识点

万能头文件
#include<bits/stdc++.h>
#include
#include
#include
#include
#include
#include<string.h>
#include

using namespace std;
string s;//string 小写
int len = s.length();
stack str;//栈

priority_queue<Type, Container, Functional>
Type为数据类型, Container为保存数据的容器,Functional为元素比较方式。
如果不写后两个参数,那么容器默认用的是vector,比较方式默认用operator<,也就是优先队列是大顶堆,队头元素最大。

memset(void *str, int c, size_t n)
str – 指向要填充的内存块。
c – 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
n – 要被设置为该值的字符数。

题目描述

有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。

输入输出格式

输入描述:输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
输出描述:给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前//优先队列?;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
如:
输入----------输出1 2 4 3
4 3
1 2
2 3
4 3

解题思路:

利用拓扑排序,节点用优先队列存储,保证输出时编号小的队伍在前。
每个队伍都是一个节点
每场比赛都是一条边
如4 3代表4→3

#include<bits/stdc++.h>
using namespace std;
const int max1=505;//矩阵存储1<=N<=500
priority_queue<int, vector<int>, greater<int> > q;//小顶堆队列
int ideg[max1]={0};//入度矩阵
vector<int> v[max1];//用链表记录后继节点
void topo(int n){
	for(int i=1;i<=n;++i){
		if(!ideg[i]) q.push(i);//入度为零入队
	}
	int flag=0;//已出队的元素个数
	while(!q.empty()){
		int now=q.top();
		q.pop();
		if(flag) printf(" %d",now);
		else printf("%d",now);
		flag++;
		for(int i=0;i<v[now].size();++i){//v[now].size()//v[now]是一个一维数组v[now].size()便是数组长度,即后继节点个数
			int next=v[now][i];
			ideg[next]--;
			if(!ideg[next]) q.push(next);
		}
	}
	if(flag!=n){
		printf("有环");
	}
}
int main(){
	int m,n;//n节点,m边
	int mpt[max1][max1];
	while(cin>>n>>m){
		memset(mpt, 0, sizeof(mpt));//memset初始化二维数组
		//for(int j=0;j<502;++j)
		//	for(int k=0;k<502;++k)
		//		mpt[j][k]=0;//一样也可初始化
		for(int i=1;i<=m;++i){
			int a,b;
			cin>>a>>b;
			mpt[a][b]=1;
		}
		for(int i=1;i<=n;++i){
			v[i].clear();//记得先清空
			for(int j=1;j<=n;++j){
				if(mpt[i][j]){
					v[i].push_back(j);
					ideg[j]++;
				}
			}
		}
		topo(n);
		//printf("\n");
		cout<<endl;
	}
	return 0;
}