九度OJ-1450:产生冠军
作者:互联网
题目描述:
有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。
球赛的规则如下:
如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。
输入:
输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。
输出:
对于每个选手群,若你判断出产生了冠军,则在一行中输出“Yes”,否则在一行中输出“No”。
样例输入:
3
Alice Bob
Smith John
Alice Smith
5
a c
c d
d e
b e
a d
0
样例输出:
Yes
No
参考代码:
/*本题好像是判断拓扑排序的存在性,但是第二个例子说明产生冠军的情况是全图存在唯一入度为0的结点*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
#include<string>
#include<vector>
using namespace std;
#define N 2010
map<string, int>ma;
//vector<int> edge[N];
int in[N];
char c1[101], c2[101];
string s1, s2;
int main() {
int n;
while (scanf("%d", &n) != EOF) {
if (n == 0) break;
for (int i = 1; i <= 2 * n; i++) {
in[i] = 0;//注意这里输入n对关系,即最多可能存在2*n个队伍
}
ma.clear();
int idx = 1;
for (int i = 1; i <= n; i++) {
scanf("%s%s", c1, c2);
s1 = c1;
s2 = c2;
int idxa, idxb;
if (ma.find(s1) == ma.end()) {
idxa = idx;
ma[s1] = idx++;;
}
else {
idxa = ma[s1];
}
if (ma.find(s2) == ma.end()) {
idxb = idx;
ma[s2] = idx++;
}
else {
idxb = ma[s2];
}
in[idxb]++;
}
int cnt = 0;
for (int j = 1; j <idx; j++) {//注意这里不带等号,即使下标从1开始
if (in[j] == 0)
cnt++;
}
puts(cnt == 1 ? "Yes" : "No");
}
return 0;
}
标签:输出,OJ,int,选手,九度,1450,冠军,include,打败 来源: https://blog.csdn.net/sinat_38292108/article/details/88343587