PAT A1148 Werewolf - Simple Version(C++)

PAT甲级目录 | PAT乙级目录

题目描述

原题地址:A1148 Werewolf - Simple Version
中文版:B1089 狼人杀-简单版

解题思路

暴力破解。

  • 每次假设其中两名玩家为狼人,并按照该假设设置所有人的身份。
  • 然后判断每个人是否说谎,即他声称的玩家身份是否与其当前设定身份一致,如果不一致则说谎。并记录每个说谎的人的编号。
  • 每人的话判断结束,如果只有两人说谎,且他们的身份为一名好人一名狼人,则输出结果并退出循环。否则调整假设继续遍历。
  • 如果遍历结束还没有找到结果,则无解。

易错点

  • 如何判断一个玩家是否说谎
    • 判断一个人是否说谎,即他声称的玩家身份是否与其当前设定身份一致,如果不一致则说谎。因为当前设定身份就是假定的真实情况,不一致说明他讲的与实际不符。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
int main() {
int n, s[105];
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &s[i]);
for(int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
vector<int> ans, id(n + 1, 1);// id 用于记录当前状态下所有人的身份
id[i] = id[j] = -1;
for (int k = 1; k <= n; k++) // 记录说谎的人
if (s[k] * id[abs(s[k])] < 0) ans.push_back(k);
if (ans.size() == 2 && id[ans[0]] + id[ans[1]] == 0){
printf("%d %d\n", i, j);//只有两个人说谎且一个是狼人一个是好人
return 0;
}
}
}
printf("No Solution\n");
return 0;
}