要求:假设一群人中有两狼人,现在给出一组一些人(狼人)对其他人(狼人)的判断,如果满足:人和狼人中各有一人撒谎,则输出这两个狼人,
方法:穷举法,(考场上居然忘记了这种方法),确切的说是没读懂题,逻辑推理差,即:假设其中两个人为狼人,其他为人,则一个一个的判断,如果最后人和狼人中各只有一个说谎,则为答案,(从小到大判断,满足要求的肯定是最小输出)判断规则如下:
他为人(狼人),说 一个人为狼人,或者说一个狼人为人,则说谎的人(狼人)加一。
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
//freopen("test.txt","r",stdin);
int N,i,j,k;
scanf("%d",&N);
vector<int>said(N+1);
for(i=1;i<=N;++i)scanf("%d",&said[i]);//第i个人说said[i]是,输入小于0为狼人,大于0为人
for(i=1;i<N;++i){ //假设i,j是狼人,其他为人
for(j=i+1;j<=N;++j){
int man=0,wolf=0,flag=0; //说谎的狼人和人的数量
for(k=1;k<=N;++k){ //一个一个测试,
if(flag)break;
if(k==i||k==j){ //当前检测的为狼人
if(said[k]>0&&(said[k]==i||said[k]==j))++wolf;//说said[k]是人,但said[k]为狼人
if(said[k]<0&&(-said[k]!=i&&-said[k]!=j))++wolf;//说said[k]是狼人,但其为人
if(wolf>1)flag=1;//两个狼人说谎
}else{ //当前检测的为人
if(said[k]<0&&(abs(said[k])!=i&&abs(said[k])!=j))++man;//说said[k]是狼人,但said[k]不是狼人
if(said[k]>0&&(said[k]==i||said[k]==j))++man;//说said[k]是人,但其是狼人
if(man>1)flag=1; //两个人说谎
}
}
if(man==1&&wolf==1){ //一次假设成立,即输出结束
printf("%d %d",i,j);
return 0;
}
}
}
printf("No Solution");
return 0;
}