Rochambeau POJ - 2912
考察:并查集+枚举
错误思路:
接收了所有的判断语句,当出现矛盾的时候玩游戏的两人犯规次数+1,输出犯规最多的人.
很明显错在有裁判的关系是不准确的,因为那段关系不能考虑
正确思路:
枚举每个可能为裁判的人,如果可能为裁判的人>1,则不能确定;如果=1,则输出此人.如果==0,则impossible
说实话,这种思路感觉有点矛盾.这样就不能判断必须为裁判的人数,而题目要求必须为裁判的人>1则输出impossible,但是此解输出不能确定.
但是看了网上基本是这种思路,或者这个思路换成不能为裁判的人数.
这题真诡异,可能是我没理解题意
易错:
每次枚举一人都要重新建树
裁判需要每个人都和他出现矛盾才能判定,没有裁判乱出子是不会出现矛盾的,我们确定矛盾是最晚出现矛盾的那句.
1 #include <iostream> 2 using namespace std;//想清楚再写题啊!!!! 3 const int N = 520; 4 int p[N],d[N],pos[N]; 5 struct game{ 6 int l,r; 7 char ans; 8 }query[2010]; 9 int findf(int x) 10 { 11 if(p[x]!=x){ 12 int t = findf(p[x]); 13 d[x]+=d[p[x]]; 14 p[x] = t; 15 } 16 return p[x]; 17 } 18 int main() 19 { 20 freopen("in.txt","r",stdin); 21 int n,m; 22 while(~scanf("%d%d",&n,&m)) 23 { 24 if(n==1) { printf("Player 0 can be determined to be the judge after 0 lines\n"); continue;} 25 fill(pos,pos+N,0); 26 int cnt = 0; int ans = 0; int id = 0; 27 //我们需要枚举裁判,因为有裁判的 关系是不准确的 28 for(int i=1;i<=m;i++) scanf("%d %c %d",&query[i].l,&query[i].ans,&query[i].r);//输入处理很妙,空格既会被跳过,多余空格还会被接受 29 for(int i=0;i<n;i++){ 30 for(int k=0;k<n;k++) p[k] = k; 31 fill(d,d+N,0); 32 for(int j=1;j<=m;j++){ 33 int x = query[j].l; int y = query[j].r; 34 if(x==i||y==i) continue; 35 int px = findf(x); int py = findf(y); 36 if(query[j].ans=='>'){ 37 if(px!=py){ 38 d[px] = 1+d[y]-d[x]; 39 p[px] = py; 40 }else{ 41 if((d[x]-d[y]-1)%3==0) continue; 42 else{ 43 pos[i]=j; break; 44 } 45 } 46 }else if(query[j].ans=='<'){ 47 if(px!=py){ 48 d[px] = d[y]-d[x]+2; 49 p[px] = py; 50 }else{ 51 if((d[x]-d[y]+ 1)%3==0) continue; 52 else{ 53 pos[i]=j; break; 54 } 55 } 56 }else{ 57 if(px!=py){ 58 d[px] = d[y]-d[x]; 59 p[px] = py; 60 }else{ 61 if((d[x]-d[y])%3==0) continue; 62 else{ 63 pos[i]=j; break; 64 } 65 } 66 } 67 } 68 } 69 for(int i=0;i<n;i++){ 70 if(!pos[i]) { cnt++; id=i;}//pos[i]==0表示它没有出现矛盾 71 else ans = max(ans,pos[i]);//出现矛盾,说明矛盾处存在裁判,但是本题我们需要看所有的人出现后判断 72 } 73 if(cnt>1) printf("Can not determine\n"); 74 else if(!cnt) printf("Impossible\n"); 75 else if(cnt==1) printf("Player %d can be determined to be the judge after %d lines\n",id,ans); 76 } 77 return 0; 78 }
通过此题也回忆了一个很妙的输入处理方式:利用scanf的空格既允许输入空格,也可以不让空格影响输入