PAT_甲級_1148 Werewolf - Simple Version

題目大意:

已知 N 名玩家中有 2 人扮演狼人角色,有 2 人說的不是實話,有狼人撒謊但並非全部狼人都在撒謊。要求你找出扮演狼人角色的是哪幾號玩家,若是有解,在一行中按遞增順序輸出 2 個狼人的編號;若是解不惟一,則輸出最小序列解;若無解則輸出 No Solution.算法

算法思路:

題意不太好理解,此題沒有考察任何算法技巧,是一個模擬題,重點在於根據給定的信息假設一個肯定條件,在搜索過程當中,出現同時符合第二個條件的就是解,具體來講就是,題目給定了2個肯定的條件,第一個就是有且僅有2個狼人,第二個就是有2人說謊,一個是狼人,一個是平民。題目既然要求給出狼人的編號,那麼搜索的全體空間就是全部人,因爲狼人有2個,因此得使用雙重循環搜索全部狼人,分別使用i和j表明2個狼人的編號(i<=j)。既然如今肯定了狼人的編號,就說明第一個肯定條件已經使用,如今就是須要知道怎麼知道一我的有說謊了,其實也很簡單,每次搜索的時候,咱們給全部人一個初始狀態,均爲1,表示平民,讓i和j爲-1表示狼人,若是有一我的k說的話指定的那我的的狀態a[k]與其如今自己的狀態不一致就說明k在說謊。具體的作法就是,使用state初始化爲1,state[i] = state[j] = -1;遍歷每個人的編號,只要a[k]*state[abs(a[k])]<0(a[k]爲k所說的那我的的身份),就說明k在說謊,記錄下來,添加進liars中,只要liars.size()==2&&state[liars[0]]+state[liars[1]]==0,說明如今找到一個解,因爲是從前日後搜索獲得的結果,編號必定是最小的,直接退出循環。spa

考場上要是碰見這個題,心態可能得崩潰。

提交結果:

image.png

AC代碼:

#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

int main(){
    int N;
    scanf("%d",&N);
    int a[N+1];
    for (int i = 1; i <= N; ++i) {
        scanf("%d",&a[i]);
    }
    // 暴力搜索,遍歷全部的狼人,找到2個說謊的人,一人是平民,一人是狼人
    for (int i = 1; i <= N; ++i) {
        for (int j = i+1; j <= N; ++j) {
            // 首先初始化每個人的狀態,假設都是平民
            int state[N+1];
            fill(state,state+N+1,1);
            //(i,j)是一對狼人
            state[i] = state[j] = -1;
            // 只要當前人說的話與那我的的身份不符合,說明在說謊
            vector<int> liars;
            state[i] = state[j] = -1;
            for (int k = 1; k <= N; ++k) {
                if(a[k]*state[abs(a[k])]<0){
                    //k在說謊,記錄下來
                    liars.push_back(k);
                }
            }
            if(liars.size()==2&&state[liars[0]]+state[liars[1]]==0){
                // 找到一組解
                printf("%d %d",i,j);
                return 0;
            }
        }
    }
    printf("No Solution");
    return 0;
}
相關文章
相關標籤/搜索