POJ1478 HDU1470 ZOJ1252 UVA592 UVALive5625 Island of Logic【暴力】


Island of Logic
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 632 Accepted: 202

Description

The Island of Logic has three kinds of inhabitants: divine beings that always tell the truth, evil beings that always lie, and human beings that are truthful during the day and lie at night. Every inhabitant recognizes the type of every other inhabitant.
A social scientist wants to visit the island. Because he is not able to distinguish the three kinds of beings only from their looks, he asks you to provide a communication analyzer that deduces facts from conversations among inhabitants. The interesting facts are whether it is day or night and what kind of beings the speakers are.

Input

The input contains several descriptions of conversations. Each description starts with an integer n, the number of statements in the conversation. The following n lines each contain one statement by an inhabitant. Every statement line begins with the speaker's name, one of the capital letters A, B, C, D, E, followed by a colon `:'. Next is one of the following kinds of statements:

I am [not] ( divine | human | evil | lying ).

X is [not] ( divine | human | evil | lying ).

It is ( day | night ).

Square brackets [] mean that the word in the brackets may or may not appear, round brackets () mean that exactly one of the alternatives separated by | must appear. X stands for some name from A, B, C, D, E. There will be no two consecutive spaces in any statement line, and at most 50 statements in a conversation.

The input is terminated by a test case starting with n = 0.

Output

For each conversation, first output the number of the conversation in the format shown in the sample output. Then print "This is impossible.", if the conversation cannot happen according to the rules or ``No facts are deducible.'', if no facts can be deduced. Otherwise print all the facts that can be deduced. Deduced facts should be printed using the following formats:

X is ( divine | human | evil ).

It is ( day | night ).

X is to be replaced by a capital letter speaker name. Facts about inhabitants must be given first (in alphabetical order), then it may be stated whether it is day or night.

The output for each conversation must be followed by a single blank line.

Sample Input

1
A: I am divine.
1
A: I am lying.
1
A: I am evil.
3
A: B is human.
B: A is evil.
A: B is evil.
0

Sample Output

Conversation #1
No facts are deducible.

Conversation #2
This is impossible.

Conversation #3
A is human.
It is night.

Conversation #4
A is evil.
B is divine.

Hint

To make things clearer, we will show the reasoning behind the third input example, where A says ``I am evil.''. What can be deduced from this? Obviously A cannot be divine, since she would be lying, similarly A cannot be evil, since she would tell the truth. Therefore, A must be human, moreover, since she is lying, it must be night. So the correct output is as shown.

In the fourth input example, it is obvious that A is lying since her two statements are contradictory. So, B can be neither human nor evil, and consequently must be divine. B always tells the truth, thus A must be evil. Voila!
Source

Southwestern European Regional Contest 1997

Regionals 1997 >> Europe - Southwestern

問題鏈接POJ1478 HDU1470 ZOJ1252 UVA592 UVALive5625 Island of Logic
問題簡述:(略)
問題分析
    邏輯推理問題,用暴力解決,邏輯有點復雜。
    對於說的每一句話,用特征來識別。
程序說明:(略)
參考鏈接:(略)
題記:(略)

AC的C++程序如下:

/* POJ1478 HDU1470 ZOJ1252 UVA592 UVALive5625 Island of Logic */

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const char *NAMES[] = { "divine", "evil", "human" };
const int DIVINE = 0, EVIL = 1, HUMAN = 2;      // 神,惡魔,人
const int DAY = 0, NIGHT = 1;
const int M = 5;        // 最多說話人數,說話者A-E
const int N = 3 * 3 * 3 * 3 * 3 * 2;       // 3*3*3*3*3*2=486(A類數*B類數*...*E類數*白天或黑夜)
const int L = 48;

int caseno = 0;
bool state[N];
int possible[M];
char s[L];

int type(int state, int p)
{
    state >>= 1;
    while (p--) state /= 3;
    return (state % 3);
}

// 謊話判定
int judge(int state, int p)
{
    int t = type(state, p);
    return (t == EVIL || (t == HUMAN && (state & 1) == NIGHT));
}

void solve()
{
    gets(s);
    int speaker = s[0] - 'A';
    if (s[3] == 'I' && s[4] == 't') {     // 有關白天和黑夜的處理(It is day or night.)
        for (int i = 0; i < N; i++) {       //  枚舉所有組合,注意每個state[i]對應一條不同的語句
            int flag = ((i & 1) == DAY && s[9] == 'd') || ((i & 1) == NIGHT && s[9] == 'n');
            if (judge(i, speaker) == flag) state[i] = false;        // 謊話判定
        }
    } else {        // 其他句子處理
        int target = (s[5] == 'a' ? speaker : s[3] - 'A');      // 談論對象
        int neg = (s[8] == 'n');        // is "not" ?
        int t = 0;
        switch (s[8 + 4 * neg])
        {
            case 'd':
                t = DIVINE;
                break;
            case 'e':
                t = EVIL;
                break;
            case 'h':
                t = HUMAN;
                break;
            case 'l':
                for (int i = 0; i < N; i++)
                    if (judge(i, speaker) == (neg ^ judge(i, target))) state[i] = false;        // 謊話判定
                return;
        }
        for (int i = 0; i < N; i++)
            if (judge(i, speaker) == (neg ^ (type(i, target) == t))) state[i] = false;      // 謊話判定
    }
}

void output()
{
    int daynight = -1;
    bool deduction = false;
    memset(possible, -1, sizeof(possible));
    for (int i = 0; i < N; i++)
        if (state[i]) {
            if (daynight != -1 && daynight != (i & 1)) daynight = -2;       // 出現多種可能
            else if (daynight == -1) daynight = i & 1;
            for (int j = 0; j < M; j++)
            {
                if (possible[j] != -1 && possible[j] != type(i, j))///出現多種可能
                    possible[j] = -2;
                else if (possible[j] == -1)
                    possible[j] = type(i, j);
            }
        }
    printf("Conversation #%d\n", ++caseno);
    if (daynight == -1) puts("This is impossible.");
    else {
        for (int i = 0; i < M; i++)
            if (possible[i] >= 0) {
                printf("%c is %s.\n", i + 'A', NAMES[possible[i]]);
                deduction = true;
            }
        if (daynight >= 0) {
            printf("It is %s.\n", daynight == DAY ? "day" : "night");
            deduction = true;
        }
        if (!deduction)
            puts("No facts are deducible.");
    }
    putchar('\n');
}

int main()
{
    int n;
    while (~scanf("%d", &n) && n) {
        getchar();
        memset(state, true, sizeof(state));
        for(int i = 0; i < n; i++)
            solve();
        output();
    }

    return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com