目录
1,题目描述
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
题目描述
狼人杀简化版。有若干个狼人和村民,有2个人撒谎,其中1个撒谎的是狼人。根据每个人的讲述判断谁是狼人。
若结果不唯一,则输出编号最小的那一组。若没有则输出No Solution。
2,思路
参考@日沉云起【pat甲级1148 Werewolf - Simple Version、pat乙级1089 狼人杀-简单版题解】
算法
- 利用两重for循环i,j分别指向两个狼人;
- 如何判定撒谎:i和j指向的是狼人,若k所指为i或j,且值data[k]<0,则其没有撒谎,否则判定为撒谎;k所指不为i或j,且值data[k]>0,则其没有撒谎,否则判定为撒谎;(可用异或^来判定是否撒谎,代码见注释)
- 记录撒谎的人的数目lier和撒谎的狼人数目wolfLier;
3,AC代码
#include<bits/stdc++.h>
using namespace std;
int N, data[105];
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d", &N);
for(int i = 1; i <= N; i++) // !!!i从1开始
scanf("%d", &data[i]);
for(int i = 1; i <= N; i++){
for(int j = i + 1; j <= N; j++){
int lier = 0, wolfLier = 0;
for(int k = 1; k <= N; k++){
// if((abs(data[k]) == i || abs(data[k]) == j) ^ (data[k] < 0)){
// lier++;
// if(k == i || k == j)
// wolfLier++;
// }
if(abs(data[k]) == i || abs(data[k]) == j){
if(data[k] > 0){
lier++;
if(k == i || k == j)
wolfLier++;
}
}else{
if(data[k] < 0){
lier++;
if(k == i || k == j)
wolfLier++;
}
}
}
if(lier == 2 && wolfLier == 1){
printf("%d %d", i, j);
return 0;
}
}
}
printf("No Solution");
return 0;
}
4,解题过程