1148 Werewolf - Simple Version (20 分) 狼人杀简化版(其实一点也不简化) 条件逻辑

1148 Werewolf - Simple Version (20 分)
Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and the human beings. Suppose that in a game,

player #1 said: "Player #2 is a werewolf.";
player #2 said: "Player #3 is a human.";
player #3 said: "Player #4 is a werewolf.";
player #4 said: "Player #5 is a human."; and
player #5 said: "Player #4 is a human.".
Given that there were 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liars. Can you point out the werewolves?

Now you are asked to solve a harder version of this problem: given that there were N players, with 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liars. You are supposed to point out the werewolves.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (5≤N≤100). Then N lines follow and the i-th line gives the statement of the i-th player (1≤i≤N), which is represented by the index of the player with a positive sign for a human and a negative sign for a werewolf.

Output Specification:
If a solution exists, print in a line in ascending order the indices of the two werewolves. The numbers must be separated by exactly one space with no extra spaces at the beginning or the end of the line. If there are more than one solution, you must output the smallest solution sequence -- that is, for two sequences A=a[1],...,a[M] and B=b[1],...,b[M], if there exists 0≤k<M such that a[i]=b[i] (i≤k) and a[k+1]<b[k+1], then A is said to be smaller than B. In case there is no solution, simply print No Solution.

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

给出n个人,以及一个发言序列,每个人声明其他人的身份,+i表示声明i为好人,-i表示声明i为狼人。其中两个狼人,有一个狼人和一个好人说了假话,让我们求出谁是狼人。

去年九月份PAT考试,当初也是第一个题狼人杀,当时把我给杀得翻皮水,磨蹭了40分钟就对了3分一个样例。这次还是不会做,思路又找错了。

首先肯定是假设来做,但是主要是假设什么呢?是假设狼人还是假设说谎者?我选择的是假设说谎者,因为我觉得只需要把假设的说谎者的话取个相反数,得到的就是最终的正确发言序列。但是这时我犯难了,如果发言者没有一个说出谁是狼人怎么办?我也无法判断两个说谎的人中谁是狼人,搞不下去了——或许能用逻辑证明这种情况并不存在,但我暂时想不出来,我也觉得在考场上一时半会无法想出来。

之后换了个方法,就是假设狼人。a[]记录每个人的发言。双重循环假设狼人是i,j,再设置一个数组se标识某个人是不是狼人,当前是除了i,j,其他人都是好人,标1;i,j标-1。数组v用于记录说谎者。从头开始遍历,如果某个人k说的和当前的假设的真实情况对不上,也就是说a[k]*se[abs(a[k])]<0,则将它加入v。最后,如果v中恰有两个元素,并且他们的身份是1狼1好人(se[v[0]]+se[v[1]]==0) ,就输出这两个数,结束程序。当所有假设都试过了,没有输出时,就输出无解。

  • 又双叒叕参考了柳婼大佬的博客。最后自己写了个"No solution",s没大写,一直报错,又改了二十分钟,就是个辣鸡。
#include <bits/stdc++.h>
#define N 105
using namespace std;
int a[N];
int main()  {
    int n;
    scanf("%d",&n);
    for (int i=1;i<=n;i++)   scanf("%d",&a[i]);
    for (int i=1;i<=n;i++)   {              //假设i和j是狼人
        for (int j=i+1;j<=n;j++)    {
            vector<int> v,se(n+1,1);          //se存储当前假设下的真实情况,-1表示i是狼人,1表示i是好人
            se[i]=se[j]=-1;
            for (int k=1;k<=n;k++)
                if (a[k]*se[abs(a[k])]<0)
                    v.push_back(k);
            if ((int)v.size()==2&&(se[v[0]]+se[v[1]]==0))  {printf("%d %d\n",i,j);return 0;}
        }
    }
    printf("No Solution\n");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值