题目概述
两人对决,必有胜负,而且这一结果不会再改变,但若干人对决,却不一定有最强的,给定N条两人对决的结果,问是否能确定最强的人
时限
1000ms/1000ms
输入
第一行正整数N,其后N行,每行两个字符串,前者总是可以战胜后者,输入到N=0结束
限制
1<=N<=1000
输出
每行一个字符串,若可确定最强的人,输出Yes,否则No
样例输入
3
Alice Bob
Smith John
Alice Smith
5
a c
c d
d e
b e
a d
0
样例输出
Yes
No
讨论
模拟?应该可以这么算,本来用的是并查集,结果越扯越乱(平时用的是带路径压缩的,容易乱套),后来想用map,更乱,看过讨论版发觉,和hdu 1172有异曲同工之妙,N组对决结果,若要确定冠军,必然最多只能有N+1个人,以及N个失败的人,最后剩下的那个就是冠军,因而只要数数有多少人败过就可以了
题解状态
46MS,1792K,754 B,C++
题解代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<string>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 1002
#define memset0(a) memset(a,0,sizeof(a))
int N;//条目数
map<string, bool>name;//记录是否失败过
void fun()
{
for (int p = 0; p < N; p++) {
string a, b;
cin >> a >> b;//input
if (name.find(a) == name.end())
name[a] = 1;//对前者 若未出现过则记为胜利
else
name[a] = name[a] < 1 ? name[a] : 1;//若出现过且失败过 则仍记为失败
name[b] = 0;//后者一定是失败的
}
int cnt = 0;//败者数目
for (auto x : name)
cnt += x.second == 0;//若失败则+1
if (cnt == name.size() - 1)
printf("Yes\n");//output//若仅有1人未曾失败则可确定
else
printf("No\n");//output
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);
while (cin >> N&&N) {//input
fun();
name.clear();//莫忘清零
}
}
EOF