Problem Description
有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。
球赛的规则如下:
如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。
球赛的规则如下:
如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。
Input
输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。
Output
对于每个选手群,若你判断出产生了冠军,则在一行中输出“Yes”,否则在一行中输出“No”。
Sample Input
3 Alice Bob Smith John Alice Smith 5 a c c d d e b e a d 0
Sample Output
Yes No
如果A打败了B,那么B一定不能成为冠军,有了这一条,一切都好办了,首先将所有的对手标记为成功,对于输入的每一个结果,如
Alice Bob,将Bob标记为失败,依次处理,到了最后再查看标记,如果成功的标记只有一条,那么一定能够行,输出Yes,没有成功的标记或者标记大于1,比赛没有冠军,输出No。
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <map>
using namespace std;
#define MAX_NUM 2000
#define MAX_NAME_LEN 32
int main()
{
//思路:只需要判断谁不是冠军即可
int mark[MAX_NUM]; //标记数组
int num_of_demo; //测试的组数
while (scanf("%d", &num_of_demo) && num_of_demo != 0)
{
string first_name, second_name;
memset(mark, 0, sizeof(mark));
map<string, int> name_map;
int index = 0; //指示器
int count = 0;
for (int i = 0; i < num_of_demo; ++i)
{
//scanf("%s %s", &first_name, &second_name);
cin >> first_name >> second_name;
map<string, int>::iterator it1, it2;
it1 = name_map.find(first_name);
it2 = name_map.find(second_name);
if (it1 == name_map.end())
{//如果不存在,插入
name_map.insert(make_pair(first_name, index++));
}
if (it2 == name_map.end())
{
name_map.insert(make_pair(second_name, index++));
mark[index - 1] = -1; //该位不可能成为冠军
}
else
{
mark[it2->second] = -1;
}
}
for (int i = 0; i < index; ++i)
{
if (mark[i] == 0)
{
count++;
}
}
if (count == 1)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}
return 0;
}