产生冠军
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5027 Accepted Submission(s): 2409
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
1 /* 功能Function Description: HDOJ-2094 2 开发环境Environment: DEV C++ 4.9.9.1 3 技术特点Technique: 4 版本Version: 5 作者Author: 可笑痴狂 6 日期Date: 20120812 7 备注Notes: -----策略问题 8 9 */ 10 11 /* 12 代码一: 13 本来想先用字典树给名字编号,然后用建立相应的邻接表,枚举每个节点然后DFS,后来发现一直wrong,看看网上的思路, 14 发现只用判断是否存在唯一一个没有被打败的人即可,就根据邻接表判断的。 15 */ 16 17 #include<stdio.h> 18 #include<string.h> 19 #include<stdlib.h> 20 21 typedef struct node 22 { 23 int code; 24 struct node *next1; 25 }node; 26 node c[2001]; 27 28 typedef struct tree 29 { 30 int order; 31 struct tree *next2[26]; 32 }tree; 33 34 tree memory[1000000]; 35 int k,m; 36 int visit[1001]; 37 38 int insert(char *a,tree *T) 39 { 40 tree *p,*q; 41 int i,j,id,flag=0; 42 p=T; 43 i=0; 44 while(a[i]) 45 { 46 id=a[i]-'a'; 47 if(p->next2[id]==NULL) 48 { 49 flag=1; 50 q=&memory[k++]; 51 q->order=0; 52 for(j=0;j<26;++j) 53 q->next2[j]=NULL; 54 p->next2[id]=q; 55 } 56 p=p->next2[id]; 57 ++i; 58 } 59 if(flag||p->order==0) 60 { 61 p->order=m++; 62 return p->order; 63 } 64 else 65 return p->order; 66 } 67 68 /* 69 void DFS(int i) 70 { 71 struct node *t; 72 for(t=c[i].next1;t;t=t->next1) 73 { 74 if(visit[t->code]) 75 continue; 76 visit[t->code]=1; 77 DFS(t->code); 78 } 79 } 80 */ 81 82 int main() 83 { 84 int n,i,flag,num1,num2; 85 char a[30],b[30]; 86 tree *T; 87 node *t1; 88 T=&memory[0]; 89 while(scanf("%d",&n),n) 90 { 91 k=1; 92 m=1; 93 T->order=0; 94 for(i=0;i<26;++i) 95 T->next2[i]=NULL; 96 for(i=1;i<=2*n;++i) 97 { 98 c[i].next1=NULL; 99 c[i].code=i; 100 } 101 for(i=1;i<=n;++i) 102 { 103 scanf("%s%s",a,b); 104 num1=insert(a,T); 105 num2=insert(b,T); 106 107 t1=(node *)malloc(sizeof(node)); 108 t1->code=num1; 109 t1->next1=c[num2].next1; 110 c[num2].next1=t1; 111 } 112 113 flag=0; 114 for(i=1;i<m;++i) 115 { 116 if(c[i].next1==NULL) 117 ++flag; 118 if(flag>1) 119 break; 120 } 121 if(flag==1) 122 printf("Yes\n"); 123 else 124 printf("No\n"); 125 /* 126 for(i=1;flag&&i<=n;++i) 127 { 128 for(j=1;j<=n;++j) 129 visit[j]=0; 130 DFS(i); 131 if(visit[i]) 132 { 133 flag=0; 134 break; 135 } 136 for(j=1;j<=n;++j) 137 { 138 if(j==i) 139 continue; 140 if(visit[j]==0) 141 { 142 flag=0; 143 break; 144 } 145 } 146 if(j==n+1) 147 break; 148 } 149 if(flag) 150 printf("Yes\n"); 151 else 152 printf("No\n"); 153 */ 154 } 155 return 0; 156 } 157 158 159 160 /* 161 //代码二: 162 题目要求产生冠军,其实,仔细看一下题目就可以知道,其实冠军的产生很简单,就是所给的数据中存在唯一没有被打败的人, 163 而对于谁打败谁,根本没有关系。换句话说,只要把所有名字列出来,并记录他们分别被打败的次数, 164 再从头到尾查一下总共多少人没有被打败过,如果只有一个人 那就yes了。 165 166 #include<stdio.h> 167 #include<string.h> 168 #include<stdlib.h> 169 170 typedef struct tree 171 { 172 int order; 173 struct tree *next[26]; 174 }tree; 175 176 tree memory[1000000]; 177 int k,m; 178 int num[2005]; 179 180 int insert(char *a,tree *T) 181 { 182 tree *p,*q; 183 int i,j,id,flag=0; 184 p=T; 185 i=0; 186 while(a[i]) 187 { 188 id=a[i]-'a'; 189 if(p->next[id]==NULL) 190 { 191 flag=1; 192 q=&memory[k++]; 193 q->order=0; 194 for(j=0;j<26;++j) 195 q->next[j]=NULL; 196 p->next[id]=q; 197 } 198 p=p->next[id]; 199 ++i; 200 } 201 if(flag||p->order==0) 202 { 203 p->order=m++; 204 return p->order; 205 } 206 else 207 return p->order; 208 } 209 210 211 int main() 212 { 213 int n,i,flag,num1,num2; 214 char a[30],b[30]; 215 tree *T; 216 T=&memory[0]; 217 while(scanf("%d",&n),n) 218 { 219 k=1; 220 m=1; 221 flag=0; 222 memset(num,0,sizeof(num)); 223 T->order=0; 224 for(i=0;i<26;++i) 225 T->next[i]=NULL; 226 for(i=1;i<=n;++i) 227 { 228 scanf("%s%s",a,b); 229 num1=insert(b,T); 230 num2=insert(a,T); 231 num[num1]++; 232 } 233 for(i=1;i<m;++i) 234 { 235 if(num[i]==0) 236 ++flag; 237 if(flag>1) 238 break; 239 } 240 if(flag==1) 241 printf("Yes\n"); 242 else 243 printf("No\n"); 244 } 245 return 0; 246 } 247 248 */