PAT-A1148/B1089 Werewolf - Simple Version/狼人杀-简单版 题目内容及题解

本文探讨了一种复杂的狼人杀游戏场景,其中玩家通过陈述来揭示身份,但包含谎言。文章提出了一种算法,通过分析玩家之间的陈述,确定哪些玩家是狼人,解决了这个逻辑谜题。

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.

以下文字摘自《灵机一动·好玩的数学》:“狼人杀”游戏分为狼人、好人两大阵营。在一局“狼人杀”游戏中,1 号玩家说:“2 号是狼人”,2 号玩家说:“3 号是好人”,3 号玩家说:“4 号是狼人”,4 号玩家说:“5 号是好人”,5 号玩家说:“4 号是好人”。已知这 5 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。扮演狼人角色的是哪两号玩家?

本题是这个问题的升级版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。要求你找出扮演狼人角色的是哪几号玩家?

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.

输入在第一行中给出一个正整数 N(5≤N≤100)。随后 N 行,第 i 行给出第 i 号玩家说的话(1≤i≤N),即一个玩家编号,用正号表示好人,负号表示狼人。

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.

如果有解,在一行中按递增顺序输出 2 个狼人的编号,其间以空格分隔,行首尾不得有多余空格。如果解不唯一,则输出最小序列解 —— 即对于两个序列 A=a[1],...,a[M] 和 B=b[1],...,b[M],若存在 0≤k<M 使得 a[i]=b[i] (i≤k),且 a[k+1]<b[k+1],则称序列 A 小于序列 B。若无解则输出 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

解题思路

  1. 读入发言记录并储存;
  2. 双层嵌套循环并用标记数组的方式尝试狼人组合;
  3. 循环中对每组发言数出有多少撒谎者,其中狼人撒谎者有几个;
  4. 发现符合“两个说谎者,其中一名狼人说谎者”的边界条件时退出循环;
  5. 输出结果并返回零值。

代码

#include<stdio.h>
#define maxn 110
int wolf[maxn],st[maxn];
int N;

int main(){
    int i,j,k;
    int w,lair;
    scanf("%d",&N);
    for(i=1;i<=N;i++){
        scanf("%d",&st[i]);
    }
    for(i=1;i<N;i++){
        wolf[i]=1;
        for(j=i+1;j<=N;j++){
            wolf[j]=1;
            w=0;
            lair=0;
            for(k=1;k<=N;k++){
                if(st[k]>0&&wolf[st[k]]==1){//lie
                    lair++;
                    if(k==i||k==j){
                        w++;
                    }
                }else if(st[k]<0&&wolf[-st[k]]==0){
                    lair++;
                    if(k==i||k==j){
                        w++;
                    }
                }
            }
            if(lair==2&&w==1){
                printf("%d %d\n",i,j);
                return 0;
            }
            wolf[j]=0;
        }
        wolf[i]=0;
    }
    printf("No Solution\n");
    return 0;
}

运行结果

 

以下是关于简单狼人游戏规则及其实现方式的总结: --- ### 简化狼人游戏规则 1. **参与人数** 游戏通常需要 6 至 12 名玩家,其中包含平民、狼人和其他特殊身份(例如预言家)。简化本可以减少角色数量。 2. **角色分配** - 平民:多数玩家担任此角色,目标是找出并投票驱逐所有狼人- 狼人:少数玩家担任此角色,目标是在不被发现的情况下消灭所有平民。 - 特殊角色(可选):如预言家、女巫等,用于增加策略深度。 3. **游戏流程** - 白天阶段:所有人讨论并投票决定驱逐一名玩家。 - 夜晚阶段:狼人选择攻击一名玩家;特殊角色执行能力(如有)。 4. **胜利条件** - 狼人获胜:当狼人的数量等于或超过平民的数量时。 - 平民获胜:成功驱逐所有狼人--- ### 简化狼人的游戏实现方式 #### 方法一:手动实现(线下玩法) - 准备卡片或纸条标明不同角色的身份。 - 主持人负责记录夜晚行动的结果以及白天的投票情况。 - 参与者轮流发言,模拟真实社交互动。 #### 方法二:编程实现(线上玩法) 可以通过编写程序来自动化大部分逻辑。以下是一个基本框架示例: ```python import random def assign_roles(num_players): roles = ['Wolf'] * 2 + ['Villager'] * (num_players - 2) random.shuffle(roles) return roles def game_loop(players, roles): day = 1 while True: print(f"\nDay {day}: Discuss and vote.") # Simulate discussion phase here. voted_out = input("Enter the index of player to be eliminated: ") if not voted_out.isdigit() or int(voted_out) >= len(players): print("Invalid choice!") continue eliminated_player = players[int(voted_out)] print(f"{eliminated_player} has been eliminated.") # Check win conditions... wolves_left = sum([1 for r in roles if r == 'Wolf']) villagers_left = sum([1 for r in roles if r != 'Wolf']) if wolves_left == 0: print("\nVillagers Win!") break elif wolves_left >= villagers_left: print("\nWolves Win!") break print("\nNight falls...") attacked_player_index = random.randint(0, len(players)-1) print(f"Wolf attacks Player {players[attacked_player_index]}.") del players[attacked_player_index] del roles[attacked_player_index] day += 1 if __name__ == "__main__": num_players = int(input("How many players? ")) players = list(range(1, num_players+1)) roles = assign_roles(num_players) print("Roles assigned:", dict(zip(players, roles))) game_loop(players, roles) ``` #### 方法三:利用现有平台 许多在线平台已经提供了简化的狼人模式,可以直接使用而无需开发新系统。例如: - Tabletop Simulator - Werewolf Online Games --- ### 注意事项 - 如果希望进一步简化规则,可以选择去掉特殊角色,只保留平民和狼人两种基础身份。 - 编程实现时需确保随机性和公平性,避免出现漏洞导致游戏失去趣味。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值