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 }

 

posted @ 2020-11-22 23:19  罪梦者  阅读(362)  评论(0)    收藏  举报