1089 狼人杀-简单版 (20分)
1089 狼人杀-简单版 (20分)
以下文字摘自《灵机一动·好玩的数学》:“狼人杀”游戏分为狼人、好人两大阵营。在一局“狼人杀”游戏中,1 号玩家说:“2 号是狼人”,2 号玩家说:“3 号是好人”,3 号玩家说:“4 号是狼人”,4 号玩家说:“5 号是好人”,5 号玩家说:“4 号是好人”。已知这 5 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。扮演狼人角色的是哪两号玩家?
本题是这个问题的升级版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。要求你找出扮演狼人角色的是哪几号玩家?
输入格式:
输入在第一行中给出一个正整数 N(5)。随后 N 行,第 i 行给出第 i 号玩家说的话(1),即一个玩家编号,用正号表示好人,负号表示狼人。
输出格式:
如果有解,在一行中按递增顺序输出 2 个狼人的编号,其间以空格分隔,行首尾不得有多余空格。如果解不唯一,则输出最小序列解 —— 即对于两个序列 [ 和 [,若存在 0 使得 [ (i≤k),且 [,则称序列 A 小于序列 B。若无解则输出 No Solution。
输入样例 1:
5
-2
+3
-4
+5
+4
输出样例 1:
1 4
输入样例 2:
6
+6
+3
+1
-5
-2
+4
输出样例 2(解不唯一):
1 5
输入样例 3:
5
-2
-3
-4
-5
-1
输出样例 3:
No Solution
代码讲解:刚开始读题的时候我就感觉到,这一看就是枚举类型的题。。。。
但是我方向有点麻烦,不断枚举的是谁说慌,导致想的东西蛮多的。。。
有一种情况我没想到。。但是不继续了。。。太麻烦,换成枚举谁是狼人要好的
多。。。。代码一,是麻烦版本。。。最后一个测试点没过去。。不继续编了。。
代码二是枚举狼人版本。。。
代码一:最后一个测试点过不去
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 int main() 5 { 6 int n,i,flag=0,j,k,count_hao=0,count_lang=0,count=0,a[201]={0},temp,result[200][2], num; 7 scanf("%d",&n); 8 int b[n+1]; 9 for(i=1;i<=n;i++) 10 scanf("%d",b+i); 11 for(i=1;i<n-1;i++) 12 { 13 for(j=i+1;j<=n;j++) 14 { 15 memset(a,0,sizeof(a)); 16 count_hao=0; 17 count_lang=0; 18 for(k=1;k<=n;k++) 19 { 20 if(k==i||k==j) 21 { 22 temp=-b[k]; 23 } 24 else 25 temp=b[k]; 26 if(a[abs(temp)]==0) 27 { 28 if(temp>0) 29 a[temp]=1,count_hao++; 30 else 31 a[-temp]=-1,count_lang++; 32 } 33 else 34 { 35 if(a[abs(temp)]*temp>0) 36 continue; 37 else 38 break; 39 } 40 41 } 42 if(k==n+1&&((count_hao==n-2&&count_lang==2)||(count_lang==2&&count_hao<n-2)||(count_hao==n-2&&count_lang<2))) //应该是有其他情况我没有想到。。。。太麻烦 43 { 44 num=0; 45 if(count_hao==n-2) 46 { 47 for(k=1;k<=n;k++) 48 { 49 if(a[k]==0) 50 a[k]=-1; 51 } 52 } 53 else 54 { 55 if(count_lang==2) 56 for(k=1;k<=n;k++) 57 { 58 if(a[k]==0) 59 a[k]=1; 60 61 } 62 } 63 if(a[i]*a[j]==-1) 64 { 65 // printf("i=%d j=%d\n",i,j); 66 flag=1; 67 for(k=1;k<=n;k++) 68 { 69 if(a[k]==-1) 70 result[count][num++]=k; 71 } 72 count++; 73 74 } 75 } 76 } 77 } 78 if(!flag) 79 printf("No Solution\n"); 80 else 81 { 82 flag=0; 83 temp=105; 84 for(i=0;i<count;i++) 85 { 86 if(result[i][0]<temp) 87 { 88 temp=result[i][0]; 89 j=i; 90 } 91 } 92 temp=result[j][1]; 93 for(i=0;i<count;i++) 94 { 95 if(result[i][0]==result[j][0]&&result[i][1]<temp) 96 { 97 temp=result[i][1]; 98 j=i; 99 } 100 } 101 printf("%d %d\n",result[j][0],result[j][1]); 102 103 } 104 105 return 0; 106 }
代码二:
1 #include<stdio.h> 2 #include<math.h> 3 int main() 4 { 5 int n,i,j,k,a[101]={0},b[101],count=0,result[101],flag=0; 6 scanf("%d",&n); 7 for(i=1;i<=n;i++) 8 scanf("%d",a+i); 9 for(j=1;j<=n;j++) 10 b[j]=1; 11 for(i=1;i<=n;i++) //枚举俩个狼人 12 { 13 b[i]=-1; 14 15 for(j=i+1;j<=n;j++) 16 { 17 count=0; 18 b[j]=-1; 19 for(k=1;k<=n;k++) 20 { 21 if(a[k]*b[abs(a[k])]<0) //判断谁说谎 22 { 23 result[count++]=k; 24 } 25 } 26 if(count==2&&b[result[0]]*b[result[1]]<0) //说谎人数是否对应,并且必须是一个好人和一个狼人 27 { 28 flag=1; 29 goto out; //为了方便跳出多重循环用了goto 30 } 31 b[j]=1; 32 } 33 b[i]=1; 34 } 35 out : 36 if(!flag) 37 printf("No Solution\n"); 38 else 39 printf("%d %d\n",i,j); 40 41 return 0; 42 }