Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and the human beings. Suppose that in a game,

  • player #1 said: "Player #2 is a werewolf.";
  • player #2 said: "Player #3 is a human.";
  • player #3 said: "Player #4 is a werewolf.";
  • player #4 said: "Player #5 is a human."; and
  • player #5 said: "Player #4 is a human.".

Given that there were 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liars. Can you point out the werewolves?

Now you are asked to solve a harder version of this problem: given that there were N players, with 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liars. You are supposed to point out the werewolves.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (5N100). Then N lines follow and the i-th line gives the statement of the i-th player (1iN), which is represented by the index of the player with a positive sign for a human and a negative sign for a werewolf.

Output Specification:

If a solution exists, print in a line in ascending order the indices of the two werewolves. The numbers must be separated by exactly one space with no extra spaces at the beginning or the end of the line. If there are more than one solution, you must output the smallest solution sequence -- that is, for two sequences A=a[1],...,a[M] and B=b[1],...,b[M], if there exists 0k<M such that a[i]=b[i] (ik) and a[k+1]<b[k+1], then A is said to be smaller than B. In case there is no solution, simply print No Solution.

Sample Input 1:

5
-2
+3
-4
+5
+4

Sample Output 1:

1 4

Sample Input 2:

6
+6
+3
+1
-5
-2
+4

Sample Output 2 (the solution is not unique):

1 5

Sample Input 3:

5
-2
-3
-4
-5
-1

Sample Output 3:

No Solution
 
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <set>
#include <vector>
using namespace std;
const int maxn=110;
int wolf[maxn];
int state[maxn];
struct node{
    int w[2];
};
bool cmp(node n1,node n2){
    return n1.w[0]==n2.w[0]?n1.w[1]<n2.w[1]:n1.w[0]<n2.w[0];
}
vector<node> v;
int main(){
  int n;
  scanf("%d",&n);
  for(int i=1;i<=n;i++){
        int tmp;
        scanf("%d",&tmp);
        state[i]=tmp;
  }
  int i,j,flag=0;
  for(i=1;i<n;i++){
        for(j=i+1;j<=n;j++){
            fill(wolf,wolf+maxn,1);
              wolf[i]=-1;
            wolf[j]=-1;
            int cnt=0;
            for(int k=1;k<=n;k++){
                if(wolf[abs(state[k])]*state[k]<0){
                    cnt++;
                }
            }
              if(cnt!=2) continue;
            else{
                if(wolf[abs(state[i])]*state[i]*wolf[abs(state[j])]*state[j]<0){
                    printf("%d %d",i,j);
                    return 0;
                }
            }
        }
   }
   printf("No Solution");
}

注意点:一开始想设置两个人说谎,然后再去判断是不是总共两个狼人一个说谎一个没有,一直有问题,分析了一下是逻辑很有问题,因为会存在有的人在陈述时会被多次点到,有的人一次都没点到,这样根据说不说谎去判断会出现很多问题,而且最后输出狼人而不是说谎的人,也会很麻烦。

因此这题需要设置两个狼人,然后判断是不是两个人说谎,并且是一狼一人。看了大佬的思路才发现判断是不是说谎只要看这个人的陈述和这个人说的人的真实身份乘起来是不是小于0,小于0就是说谎,负负得正,正负得负的思路。