1148 Werewolf - Simple Version (20point(s))

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 (5≤N≤100). Then N lines follow and the i-th line gives the statement of the i-th player (1≤i≤N), 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 0≤k<M such that a[i]=b[i] (i≤k) 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
  • 思路:

N的数量级很小,枚举肯定能解决,问题的关键是枚举啥?

有狼人撒谎但并不是所有狼人都在撒谎 :一共2个狼,所以必有一狼说谎,一狼说实话,即说谎的是一狼一民;

a. 第一想法是枚举说谎的人,假设说谎的人为i和j,(i, j) 可能为(狼,狼)(民,民)(狼,民)(民,狼),前两个样例错误

核心代码:不知道对不对…

bool Check(int liar1, int liar2, int n){
	word[liar1] = -word[liar1];
	word[liar2] = -word[liar2];
	int w_num = 0;
	for(int i = 1; i <= n; ++i){
		if(word[i] < 0){
			int wolf = -word[i];
			if(wolf == liar1 || wolf == liar2){
				w_num++;	
			}
		}
	}
	word[liar1] = -word[liar1];
	word[liar2] = -word[liar2];
	if(w.size() == 2 && w_num == 1) return true;
	else return false;
}

但是!!! 题目要求输出狼而且是最小序列,枚举出说谎的人没卵用,即使通过说谎的人得到狼序列,想找出最小序列也巨麻烦…故弃之

b. 第二种枚举方案就是枚举狼人(应该没别的枚举方案了8,毕竟只有说谎者和狼人数量是确定的 = 2 。好人数量为n-2,说实话的人也是n-2,都是变量没法枚举)
假设(i, j)是狼人,遍历word[]数组(每个人的声明),可以知道i是否说谎(说word[i]是狼但其不是:不是i j ,或说不是狼却是:i j之一),若说谎者人数为2(liar == 2),其中有且仅有一个为狼,即ijw_liar == 1),假设成立,否则假设不成立

  • code:
#include <bits/stdc++.h>
using namespace std;
vector<int> word(150);
bool isWolf(int x, int w1, int w2){
	if(x == w1 || x == w2) return true;
	else return false;
}
bool Check(int w1, int w2, int n){
	int liar = 0, w_liar = 0;
	for(int i = 1; i <= n; ++i){
		if(word[i] < 0){	//i说-word[i]是狼 
			if(!isWolf(-word[i], w1, w2)){
				liar++;	//i说谎 
				if(isWolf(i, w1, w2)) w_liar++;
			} 		
		}else{	//i说word[i]是好人 
			if(isWolf(word[i], w1, w2)){
				liar++;
				if(isWolf(i, w1, w2)) w_liar++;
			}
		}
	}
	if(liar == 2 && w_liar == 1) return true;
	else return false;
}

int main(){
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		char c;
		int tmp;
		getchar();
		scanf("%c", &c);
		scanf("%d", &tmp);
		if(c == '-') word[i] = -tmp;
		else word[i] = tmp;
	}
	
	for(int i = 1; i <= n; ++i){
		for(int j = i+1; j <= n; ++j){
			if(Check(i, j, n)){
				printf("%d %d", i, j);
				return 0;
			} 
		}
	}
	printf("No Solution");
	return 0;
}
  • T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int seq[maxn];
bool isWolf(int x, int w1, int w2){
	return x == w1 || x == w2 ? true : false;
}
bool Judge(int s, int w1, int w2){	//判断一个人是否说谎,假设w1, w2是狼 true:说谎 , false:没说谎 
	int p = abs(s);
	if(isWolf(p, w1, w2)){	//实际p是狼 
		return s < 0 ? false : true;	//若负:指认正确,正:指认错误 
	}else{ 
		return s < 0 ? true : false;
	} 
}
int main(){
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		scanf("%d", &seq[i]);
	}
	for(int i = 1; i <= n; ++i){
		for(int j = i + 1; j <= n; ++j){
			int w_liars = 0, p_liars = 0;
			for(int k = 1; k <= n; ++k){
				if(Judge(seq[k], i, j)){
					if(isWolf(k, i, j)) w_liars++;
					else p_liars++;
				} 
			}
			if(w_liars == 1 && p_liars == 1){
				printf("%d %d", i, j);
				return 0;
			} 
		}
	}
	printf("No Solution");
	return 0;
}
发布了271 篇原创文章 · 获赞 5 · 访问量 6512

猜你喜欢

转载自blog.csdn.net/qq_42347617/article/details/104244880