1089 狼人杀-简单版

第一次做的时候,难得简直让人怀疑人生。。。看别人的代码也搞不懂怎么做。

 那天我百度了好久,终于找到了一个比较接地气的题解,总算搞懂了。。。。

这是第二次做了,分析了一波很快就AC了。

题目:

思路分析:

根据题意可以很快得出一个结论,即在N个玩家中,有且仅有一个狼人,一个好人说谎。

首先,我们假设 I,J两个玩家是狼人,

然后,找出所有说谎的玩家。

最后,如果 说谎的玩家有且仅有两位,并且一个是狼人,一个是好人,那么I,J两个玩家是狼人的假设成立

那么,怎么判断玩家是否说谎呢?

情况一,某玩家说别人是狼人(给出一个负数),但是别人是好人(好人标记为 +1,即正数),那么该玩家说谎了。

情况二,某玩家说别人是好人(给出一个正数),但是别人是狼人(狼人标记为 -1,即负数 ),那么该玩家说谎了。

总结就是,当 say[k] * flag < 0时,那么第k个玩家说谎了。

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int say[111] = {0};//记录玩家说的话
 7 int main() {
 8     int n,i,j,FLAG = 0;//FLAG为 0表示不存在答案
 9     cin>>n;
10     for(i = 1; i <= n; ++i) //记录所有玩家说的话
11         scanf("%d",&say[i]);
12     for(i = 1; i <= n&&FLAG == 0; ++i) { //假设 i,j玩家是狼人
13         for(j = i+1; j <= n&&FLAG == 0; ++j) {
14             vector<int> flag(n+1,1);     //标记所有玩家是好人为 +1。
15             flag[i] = -1,flag[j] = -1;   //标记i,j玩家是狼人为 -1
16             vector<int> lie;             //存放说谎的玩家
17             for(int k = 1; k <= n; ++k) {//遍历所有玩家,判断玩家是否说谎
18                 if(say[k]*flag[abs(say[k])] < 0)
19                     lie.push_back(k);
20             }
21             //有且仅有两个玩家撒谎,并且一个是狼人,一个是好人
22             if(lie.size() == 2 &&flag[lie[0]]*flag[lie[1]] < 0) { 
23                 printf("%d %d",i,j);//输出两个狼人玩家的编号 
24                 FLAG = 1; 
25             }
26         }
27     }
28     if(FLAG == 0) printf("No Solution");
29     return 0;
30 }

 

posted @ 2020-02-26 16:21  tangq123  阅读(311)  评论(0编辑  收藏  举报