[Noip2003] 侦探推理

题目描述

明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:

证词中出现的其他话,都不列入逻辑推理的内容。

明明所知道的是,他的同学中有NNN个人始终说假话,其余的人始终说真。

现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!

输入输出格式

输入格式:

输入由若干行组成,第一行有三个整数,M(1≤M≤20)M(1≤M≤20)M(1M20)、N(1≤N≤M)N(1≤N≤M)N(1NM)和P(1≤P≤100)P(1≤P≤100)P(1P100);MMM是参加游戏的明明的同学数,NNN是其中始终说谎的人数,PPP是证言的总数。

接下来MMM行,每行是明明的一个同学的名字(英文字母组成,没有空格,全部大写)。

往后有PPP行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250250250个字符。

输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。

输出格式:

如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 "Cannot Determine";如果程序判断出没有人可能成为罪犯,则输出 "Impossible"。

输入输出样例

输入样例#1: 复制
3 1 5
MIKE
CHARLES
KATE
MIKE: I am guilty.
MIKE: Today is Sunday.
CHARLES: MIKE is guilty.
KATE: I am guilty.
KATE: How are you??
输出样例#1: 复制
MIKE





这题真恶心,真恶心。
Linux下换行符是'\r',被坑了好久。
getline加上这个就A了。
主要还是暴力。
枚举哪个人是罪犯,枚举今天是星期几,然后每一句话的真假都很好判断。
然后判断是否一个人的话有真有假...如果有这样的话直接退出找别的。
大力的判断写到一半确实有点晕...
最后再强调一下,Linux下的换行符号是'\r'!!!!!!
别问我为什么这么强调,你尝试一下本地AC提交全WA的感受就行了233.


 
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
#define reg register

int n, m, q;

string name[25];
string Theday[10] = {
    "Today is Monday.",
    "Today is Tuesday.",
    "Today is Wednesday.",
    "Today is Thursday.",
    "Today is Friday.",
    "Today is Saturday.",
    "Today is Sunday.",
};

string Dia[105]; 
bool useless[105];
int typ[105];
int opt[25];//-1 means true, 1 means false
int ans, nofa; 
int who[105];
bool flas;

int main()
{
    scanf("%d%d%d", &n, &m ,&q);
    for (reg int i = 1 ; i <= n ; i ++) cin >> name[i];
    getchar();
    for (reg int i = 1 ; i <= q ; i ++) 
    {
        string in;
        cin >> in;
        in.erase(in.end() - 1);
        for (reg int j = 1 ; j <= n ; j ++) if (in == name[j]) who[i] = j;
        getline(cin, Dia[i], '\r');
        Dia[i].erase(Dia[i].begin());
    }
    for (reg int i = 1 ; i <= q ; i ++)
    {
        for (reg int j = 0 ; j < 7 ; j ++) 
                if (Dia[i] == Theday[j]) {typ[i] = 1;goto End;}
        if (Dia[i] == "I am guilty." or Dia[i] == "I am not guilty.") {typ[i] = 2;goto End;}
        for (reg int k = 1 ; k <= n ; k ++)
            if (Dia[i] == name[k] + " is guilty." or Dia[i] == name[k] + " is not guilty.") {typ[i] = 3;goto End;}        
        useless[i] = 1;
        End:;
    }
    for (reg int p = 1 ; p <= n ; p ++) 
    {
        for (reg int tod = 0 ; tod < 7 ; tod ++)
        {
            int jia = 0, bz = 0;
            memset(opt, 0, sizeof opt);
            for (reg int i = 1 ; i <= q ; i ++)
            {
                if (useless[i]) continue;
                if (typ[i] == 1) {
                    for (reg int j = 0 ; j < 7 ; j ++)
                        if (Dia[i] == Theday[j]) {
                            if (j == tod) if (opt[who[i]] == 1) goto Break;else opt[who[i]] = -1;
                            if (j != tod) if (opt[who[i]] == -1) goto Break;else opt[who[i]] = 1;
                        }
                }
                if (typ[i] == 2) {
                    if (Dia[i] == "I am guilty.") {
                        if (who[i] == p) if (opt[who[i]] == 1) goto Break;else opt[who[i]] = -1;
                        if (who[i] != p) if (opt[who[i]] == -1) goto Break;else opt[who[i]] = 1;
                    }
                    if (Dia[i] == "I am not guilty.") {
                        if (who[i] != p) if (opt[who[i]] == 1) goto Break;else opt[who[i]] = -1;
                        if (who[i] == p) if (opt[who[i]] == -1) goto Break;else opt[who[i]] = 1;
                    }
                }
                if (typ[i] == 3) {
                    for (reg int j = 1 ; j <= n ; j ++) {
                        if (Dia[i] == name[j] + " is guilty.") {
                            if (j == p) if (opt[who[i]] == 1) goto Break;else opt[who[i]] = -1;
                            if (j != p) if (opt[who[i]] == -1) goto Break;else opt[who[i]] = 1;                            
                        }
                        if (Dia[i] == name[j] + " is not guilty.") {
                            if (j != p) if (opt[who[i]] == 1) goto Break;else opt[who[i]] = -1;
                            if (j == p) if (opt[who[i]] == -1) goto Break;else opt[who[i]] = 1;                        
                        }
                    }
                }
            }
            for (reg int i = 1 ; i <= n ; i ++) 
            {
                if (opt[i] == 1) jia++;
                if (opt[i] == 0) bz++;
            }
            if (jia <= m and bz + jia >= m) 
            {
                if (ans and ans != p) return puts("Cannot Determine"), 0;
                ans = p;
            }
            Break:;
        }
    }
    if (!ans) return puts("Impossible"), 0;
    cout << name[ans] << endl;
    return 0;
}

 

 
posted @ 2018-09-03 20:21  zZhBr  阅读(236)  评论(0编辑  收藏  举报