[Noip2003] 侦探推理
题目描述
明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:
证词中出现的其他话,都不列入逻辑推理的内容。
明明所知道的是,他的同学中有NNN个人始终说假话,其余的人始终说真。
现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!
输入输出格式
输入格式:输入由若干行组成,第一行有三个整数,M(1≤M≤20)M(1≤M≤20)M(1≤M≤20)、N(1≤N≤M)N(1≤N≤M)N(1≤N≤M)和P(1≤P≤100)P(1≤P≤100)P(1≤P≤100);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; }