想通思路程序就很简单。
根据题目意思,有两个狼人,并且有一个狼人说谎,一个平民说谎,只要统计一个序列狼人平民说谎人数就可以,也就是程序中的wCnt和hCnt,只要最后都等于1,说明有解。
遍历所有情况,当然要i≠j,只要有解就break,因为要求输出最小序列解
代码如下:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int S[510];
bool isLegal(int n,int x,int y) //x,y 是狼人
{
int hCnt = 0,wCnt = 0; //平民、狼人撒谎的人数
for(int i=1;i<=n;i++){
if(i==x||i==y){ //如果i是狼人
if(S[i]<0 && abs(S[i])!=x && abs(S[i])!=y){
wCnt++;
}
else if(S[i]>0 && (S[i]==x||S[i]==y)){
wCnt++;
}
}
else{ //如果i是平民
if(S[i]<0 && abs(S[i])!=x && abs(S[i])!=y){
hCnt++;
}
else if(S[i]>0 && (S[i]==x||S[i]==y)){
hCnt++;
}
}
}
if(hCnt==1 && wCnt==1)return true;
else return false;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&S[i]);
int flag = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i!=j && isLegal(n,i,j)){
printf("%d %d",i,j);
flag = 1;
break;
}
}
if(flag)break;
}
if(flag == 0)printf("No Solution");
return 0;
}