#include <iostream>
#include <set>
using namespace std;
set<int>no[100005];
int main()
{
int n;
//while(cin>>n)
{
cin >> n;
int a[105];
for (int i = 1; i <= n; i++)
cin >> a[i];
//题目:有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。
//有两个狼,有两个人说谎,并且有狼说谎,但不是所有狼说谎,意思是有一个狼说谎有一个人说谎
int flag = 1;
for (int i = 1; i <= n && flag!=-1; i++)//假设狼1是编号为1的人
{
for (int j = 1; j <= n && flag!=-1; j++)//假设狼2是编号为2的人
{
if (i == j)continue;
int lier = 0, lierl=0;
flag = 1;
for (int k = 1; k <= n; k++)
{
if (a[k] < 0)//在说一个狼 这个狼的是-a[k] 被k指出 编号为t
{
int t = -a[k];
if (t != i && t != j)//如果说这个被谈论的狼既不是狼1也不是狼2那么k这个家伙在说谎
{
if (k == i || k == j)
lierl++;
else
lier++;
}
if (lier > 1 || lierl > 1)//若出现了第二个说谎的人或者第二个说谎的人那么假设有误 重新进行假设。
{
flag = 0;
break;
}
}
else// 在说一个好人 这个好人是a[k] 被k指出 编号为t
{
int t = a[k];
if (t == i || t == j)
{
if (k == i || k == j)
lierl++;
else
lier++;
}
if (lier > 1 || lierl > 1)//若出现了第二个说谎的人或者第二个说谎的人那么假设有误 重新进行假设。
{
flag = 0;
break;
}
}
}
if (flag && lier==1 && lierl==1)
{
flag = -1;
cout << i << " " << j << endl;
}
}
}
if (flag != -1)
{
cout << "No Solution" << endl;
}
}
return 0;
}
看的博客……
本来是想枚举说谎的人,但是我只枚举了一个。
然后想到如果有人说k是狼又有人说k是人,那么这两个人一定有一个人在说谎,然后看到第二个案例我又蒙了。
最后是这个最小序列,我竟然最开始想的是用string存起来排你敢信……
思路很简单注释基本都全了,如果这边没法看全注释可以复制下来放记事本上看,应该比较详细了,然后可以自己拿笔模拟一下。
这个题真的不难,毕竟只有20分。
当然出于畏难心理,我犹犹豫豫的写的,完了还错了一发,而且只有一个是答案正确,万念俱灰下开始对拍,然后惊奇的发现是no solution那边错了……= =|||
这个故事告诉我们,要先测完所有的案例之后再提交。
不要着急。