Time Limit: 1 second Memory Limit: 50 MB
【问题描述】
明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:证词中出现的其他话,都不列入逻辑推理的内容。 明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。 现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!
【输入】
共m+p+1行;第一行是有二个整数,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100); M是参加游戏的明明的同学数,N是其中始终说谎的人数,P是证言的总数。接下来M行,每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。 往后有P行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250个字符。 输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。【输出】
如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是 罪犯,则输出 Cannot Determine;如果程序判断出没有人可能成为罪犯,则输出 Impossible。【输入样例】
3 1 5MIKECHARLESKATEMIKE:I am guilty.MIKE:Today is Sunday.CHARLES:MIKE is guilty.KATE:I am guilty.KATE:How are you??【输出样例】
MIKE【题目链接】:http://noi.qz5z.com/viewtask.asp?id=b302
【题意】
【题解】 题目描述不清啊 可以确定凶手的有两种情况 一种是确定m-1个人不是凶手。 另外一种是确定了一个人是凶手。 这里impossible的情况有两种 一种是全都不是凶手,另外一种就是无法达到满足的要求,即N个人说谎然后P条话都不冲突; 然后无法确定的就是剩余的; 有点迷。 不用理这种题。 (冒号后面还有一个空格。。。) O(2^m)*p爆搜就好 【完整代码】
#include <cstdio>#include <cmath>#include <algorithm>#include <string>#include <iostream>#include <map>#include <cstring>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define LL long long#define rep1(i,a,b) for (int i = a;i <= b;i++)#define rep2(i,a,b) for (int i = a;i >= b;i--)#define mp make_pair#define pb push_back#define fi first#define se second#define rei(x) scanf("%d",&x)#define rel(x) scanf("%lld",&x)typedef pair<int, int> pii;typedef pair<LL, LL> pll;const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };const double pi = acos(-1.0);const int N = 20+10;const int P = 100 + 50;struct abc{ int id, who,author; int xingqi;};int m, n, p,tot,ma = 0;bool bo[N],is[N],notis[N],xingqi[N];string name[N];string t;char ts[300];abc xinxi[P];map <string, int> dic;map <string, int> dic2;void sear_ch(){ int today = -1; memset(xingqi, true, sizeof xingqi); memset(is, false, sizeof is), memset(notis, false, sizeof notis); rep1(i, 1, tot) if (bo[xinxi[i].author]) { if (xinxi[i].id == 2) { if (today == -1) { if (!xingqi[xinxi[i].xingqi]) return; today = xinxi[i].xingqi; } else { if (today != xinxi[i].xingqi) return; } } else { int y = xinxi[i].who; if (xinxi[i].id == 0) { if (is[y]) return; notis[y] = true; } else { if (notis[y]) return; is[y] = true; } } } else if (!bo[xinxi[i].author]) { if (xinxi[i].id == 2) { if (today == xinxi[i].xingqi) return; xingqi[xinxi[i].xingqi] = false; } else { int y = xinxi[i].who; if (xinxi[i].id == 0) { if (notis[y]) return; is[y] = true; } else//说y是凶手 { if (is[y]) return; notis[y] = true; } } } int cnt = 0,j = -1,cntnot = 0; rep1(i, 1, m) { if (is[i]) cnt++, j = i; if (notis[i]) cntnot++; } if (cnt == 1) { cout << name[j] << endl; exit(0); } if (cntnot == m - 1) { rep1(i, 1, m) if (!notis[i]) cout << name[i] << endl; exit(0); } if (cntnot == m) puts("Impossible"); else puts("Cannot Determine"); exit(0);}void dfs(int x, int now){ if (x > m) { if (now == n) { sear_ch(); } return; } bo[x] = false; dfs(x + 1, now + 1); bo[x] = true; dfs(x + 1, now);}int main(){ //freopen("F://rush.txt", "r", stdin); memset(bo, true, sizeof bo); dic2["Monday"] = 1, dic2["Tuesday"] = 2, dic2["Wednesday"] = 3, dic2["Thursday"] = 4; dic2["Friday"] = 5, dic2["Saturday"] = 6, dic2["Sunday"] = 7;//处理出星期对应的数字 rei(m), rei(n), rei(p); rep1(i, 1, m) { cin >> name[i]; dic[name[i]] = i;//为每个名字搞hash对应到它的标号 } char tt = getchar(); rep1(i, 1, p) { cin.getline(ts, 300); t = string(ts); t += ' ';//在末尾加上一个空格,方便获取信息 int po = t.find(':', 0); string who = t.substr(0, po);//把说话的人提取出来 t.erase(0, po + 2);//把说话人和冒号去掉 string s[5]; rep1(j, 1, 4)//只找前4个单词 { s[j] = ""; if (t == "") { rep1(k, j + 1, 4) s[k] = ""; break;//空掉了就结束 } po = t.find(' ', 0); s[j] = t.substr(0, po);//否则把那个单词搞出来 t.erase(0, po + 1);//连同空格删掉 } if (s[3] == "") continue;//如果没有3个单词肯定不是信息 if (s[1] == "I" && s[2] == "am" && s[3] == "guilty.") xinxi[++tot].who = dic[who],xinxi[tot].id = 1,xinxi[tot].author = dic[who]; if (s[1] == "I" && s[2] == "am" && s[3] == "not" && s[4]== "guilty.") xinxi[++tot].who = dic[who], xinxi[tot].id = 0, xinxi[tot].author = dic[who]; if (s[2] == "is" && s[3] == "guilty.") xinxi[++tot].who = dic[s[1]], xinxi[tot].id = 1, xinxi[tot].author = dic[who]; if (s[2] == "is" && s[3] == "not" && s[4] == "guilty.") xinxi[++tot].who = dic[s[1]], xinxi[tot].id = 0, xinxi[tot].author = dic[who]; if (s[4] != "") continue; s[3].erase(int(s[3].size()) - 1, 1); if (s[1] == "Today" && s[2] == "is" && dic2[s[3]]) xinxi[++tot].id = 2, xinxi[tot].xingqi = dic2[s[3]],xinxi[tot].author = dic[who]; } dfs(1, 0); puts("Impossible"); return 0;}新闻热点
疑难解答