首页 > 代码库 > poj2912 Rochambeau
poj2912 Rochambeau
Description
N children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is the judge. The rest children are divided into three groups (it is possible that some group is empty). You don’t know who is the judge, or how the children are grouped. Then the children start playing Rochambeau game for M rounds. Each round two children are arbitrarily selected to play Rochambeau for one once, and you will be told the outcome while not knowing which gesture the children presented. It is known that the children in the same group would present the same gesture (hence, two children in the same group always get draw when playing) and different groups for different gestures. The judge would present gesture randomly each time, hence no one knows what gesture the judge would present. Can you guess who is the judge after after the game ends? If you can, after how many rounds can you find out the judge at the earliest?
Input
Input contains multiple test cases. Each test case starts with two integers N and M (1 ≤ N ≤ 500, 0 ≤ M ≤ 2,000) in one line, which are the number of children and the number of rounds. Following are M lines, each line contains two integers in [0, N) separated by one symbol. The two integers are the IDs of the two children selected to play Rochambeau for this round. The symbol may be “=”, “>” or “<”, referring to a draw, that first child wins and that second child wins respectively.
Output
There is only one line for each test case. If the judge can be found, print the ID of the judge, and the least number of rounds after which the judge can be uniquely determined. If the judge can not be found, or the outcomes of the M rounds of game are inconsistent, print the corresponding message.
Sample Input
3 30<11<22<03 50<10>11<21>20<24 40<10>12<32>31 0
Sample Output
Can not determinePlayer 1 can be determined to be the judge after 4 linesImpossiblePlayer 0 can be determined to be the judge after 0 lines
题目大意:小朋友们玩石头剪刀布,决定了出什么之后就会一直出什么。除了裁判,裁判每次出的招式可能不一样。给出几组比试结果,求出谁是裁判。如果能求出则写出最少在几组比试结果之后就能得出结果。如果求不出,则给出不可能求得出或者是结果可能性太多无法判定。
思路:并查集食物链的加强版。在求出父亲的同时,还增加了一个关系说明。a[x]表示x与其父亲fx的关系。1:fx<x。2:fx>x。3:fx=x。
每次求出父亲的时候还要计算他们之间的关系。
求裁判时,枚举谁是裁判。然后将裁判的出拳结果出数据中去掉,接下来开始求小朋友间的胜负关系是否矛盾。如果出了去除裁判k之外,去除其他都会得出矛盾,则裁判是k。如果去除多个数都没有矛盾,裁判无法判断。如果去除谁有矛盾,则不可能求出结果。
/* * Author: Joshua * Created Time: 2014年07月12日 星期六 10时47分42秒 * File Name: poj2912.cpp */#include<cstdio>#include<algorithm>#include<cstring>#define maxn 505#define maxm 2005using namespace std;typedef long long LL;int n,m;int a[maxn],f[maxn];int gf(int x){ if (f[x]!=x) { int fx=f[x]; f[x]=gf(f[x]); a[x]=(a[x]+a[fx])%3; } return f[x];}void solve(){ int x[maxm],y[maxm],p[maxm]; int ans,err,step=0,gfx,gfy,type,xx,yy,cnt=0; char c; for (int i=1;i<=m;++i) { scanf("%d%c%d",&x[i],&c,&y[i]); if (c==‘<‘) p[i]=1; if (c==‘>‘) p[i]=2; if (c==‘=‘) p[i]=0; } for (int i=0;i<n;++i) { for (int j=0;j<n;++j) { a[j]=0; f[j]=j; } err=0; for (int j=1;j<=m && !err;++j) { xx=x[j]; yy=y[j]; if (xx==i || yy==i) continue; gfx=gf(xx); gfy=gf(yy); type=(a[xx]-a[yy]+p[j]+3)%3; if (gfy!=gfx) { f[gfy]=gfx; a[gfy]=type; } else if ((a[xx]+p[j])%3!=a[yy]) err=j; } if (err) { cnt++; step=max(step,err); } else ans=i; } if (cnt==n) printf("Impossible\n"); else if (cnt<n-1) printf("Can not determine\n"); else printf("Player %d can be determined to be the judge after %d lines\n",ans,step);}int main(){ while (scanf("%d%d",&n,&m)==2) { solve(); } return 0;}