比赛名次
题目描述:
有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队。
输出描述:
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。 其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
输入样例:
4 3 1 2 2 3 4 3
输出样例:
1 2 4 3
解题思路:
小米校招题。用一个vector来存放 i 战胜的队伍v[i],用loser来记录队伍 i 输掉比赛的次数loser[i],然后采用升序的优先队列来对问题进行求解。先把没输过的队伍 i 放入优先队列中,然后遍历 i 赢过的队伍 j,让loser[j]–,若loser[j]==0就把j放入优先队列中,疯狂输出直到队列为空为止。
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define Up(i,a,b) for(int i = a; i <= b; i++)
#define ms(a,x) memset(a,x,sizeof(a))
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int N,M; //N个队伍,M组数据
while(cin >> N >> M)
{
vector<int> v[N+1]; //v[i]用来存放i战胜的队伍
int loser[N+1]; //loser[i]用来存放i输掉比赛的次数
ms(loser,0);
while(M--)
{
int a,b; //a胜了b
cin >> a >> b;
v[a].push_back(b);
loser[b]++;
}
priority_queue<int,vector<int>,greater<int> > pq; //升序的优先队列
Up(i,1,N)
{
if(!loser[i]) //队伍i没有输过就放入优先队列
{
pq.push(i);
}
}
int cnt = 1;
while(!pq.empty()) //输出比赛名次
{
int _ = pq.top();
pq.pop();
printf("%d%s", _,cnt==N?"\n":" "); //注意输出格式
cnt++;
int sz = v[_].size()-1;
Up(i,0,sz)
{
int j = v[_][i];
loser[j]--;
if(loser[j] == 0)
{
pq.push(j);
}
}
}
}
return 0;
}
还没有任何评论,你来说两句吧!