题目链接:http://poj.org/problem?id=2912
题意:给n个人,m组关系,玩石头剪刀布的游戏,n个人中除一个人judge以外,其他人属于3个group(即石头、剪刀、布),他们只能出这一个手势,而judge可以随便出,要求能否找到judge和在第几组关系时能最先找到judge。
思路:poj1182食物链的进阶版,与那题不同的是,这里需要枚举0到n-1,枚举i假设其为judge,然后遍历不包含i的所有关系,如果符合条件,则i就是judge,否则其不是judge,记录其判断出不是judge的那条边line(后面要用),遍历结束之后,如果judge数目num<1,则Impossible,若num>1,则Can not determine,若num=1,则其为judge,但需要输出判断其为judge的最小的line,其实也就是其它非judge判断为非judge的边line的最大值,这里有点巧妙。
其余的就和食物链一样了,x->y=-1(<),0(=),1(>),且 x->z=(x->y+y->z+4)%3-1,公式自己手动算一下就明白了。
AC代码:
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 struct node{ 6 int x,y; 7 char c; 8 }a[2005]; 9 10 int n,m,root[505],f[505],ans[505],res,num; 11 12 int getr(int k){ 13 if(root[k]==k) return k; 14 else{ 15 int tmp=root[k]; 16 root[k]=getr(root[k]); 17 f[k]=(f[k]+f[tmp]+4)%3-1; 18 return root[k]; 19 } 20 } 21 22 int main(){ 23 while(~scanf("%d%d",&n,&m)){ 24 if(!m){ 25 if(n==1) 26 printf("Player 0 can be determined to be the judge after 0 lines\n"); 27 else 28 printf("Can not determine"); 29 continue; 30 } 31 memset(ans,0,sizeof(ans)); 32 num=0; 33 for(int i=1;i<=m;++i) 34 scanf("%d%c%d",&a[i].x,&a[i].c,&a[i].y); 35 for(int i=0;i<n;++i){ 36 bool flag=true; 37 for(int j=0;j<n;++j) 38 root[j]=j,f[j]=0; 39 for(int j=1;j<=m;++j){ 40 if(a[j].x!=i&&a[j].y!=i){ 41 int t1=a[j].x,t2=a[j].y,t3,r1,r2; 42 if(a[j].c==‘<‘) t3=-1; 43 else if(a[j].c==‘=‘) t3=0; 44 else t3=1; 45 r1=getr(t1),r2=getr(t2); 46 if(r1==r2){ 47 if(f[t1]!=(t3+f[t2]+4)%3-1){ 48 ans[i]=j; 49 flag=false; 50 break; 51 } 52 } 53 else{ 54 root[r2]=r1; 55 f[r2]=(-((t3+f[t2]+4)%3-1)+f[t1]+4)%3-1; 56 } 57 } 58 } 59 if(flag) 60 ++num,res=i; 61 } 62 if(num<1) 63 printf("Impossible\n"); 64 else if(num>1) 65 printf("Can not determine\n"); 66 else{ 67 int Max=0; 68 for(int i=0;i<n;++i) 69 if(ans[i]>Max) 70 Max=ans[i]; 71 printf("Player %d can be determined to be the judge after %d lines\n",res,Max); 72 } 73 } 74 return 0; 75 }
原文地址:https://www.cnblogs.com/FrankChen831X/p/10659338.html
时间: 2024-10-08 10:42:24