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 5
MIKE
CHARLES
KATE
MIKE: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;
}

【b302】侦探推理的更多相关文章

  1. NOIP2003 侦探推理

    题二    侦探推理 [问题描述] 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯( ...

  2. 洛谷P1039 侦探推理(模拟)

    侦探推理 题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情 ...

  3. 【洛谷P1039】侦探推理

    侦探推理 题目链接 这是一道恶心至极的模拟题 我们可以枚举罪犯是谁,今天是星期几,从而判断每个人说的话是真是假 若每个人说的话的真假一致,且说谎话的人数<=k且说真话的人数<=m-k,就是 ...

  4. Luogu P1039 侦探推理(模拟+枚举)

    P1039 侦探推理 题意 题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯 ...

  5. P1039 侦探推理

    题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...

  6. [NOIP2003] 提高组 洛谷P1039 侦探推理

    题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...

  7. Luogu1039 侦探推理

    题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...

  8. P1039 侦探推理(洛谷)

    昨天做了一个非常神奇的题,告诉我们做题之前一定要好好检测评测姬! 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先 ...

  9. 洛谷 P1039侦探推理

    /* 枚举罪犯和星期几,那么所有人说的话是真是假一目了然. 首先一个人不能既说真话又说假话. 即: I am guilty. I am not guilty. 因为非真即假,所以直接判断impossi ...

随机推荐

  1. 洛谷 P2646 数数zzy

    P2646 数数zzy 题目描述 zzy自从数学考试连续跪掉之后,上数学课就从来不认真听了(事实上他以前也不认真听).于是他开始在草稿纸上写写画画,比如写一串奇怪的字符串.然后他决定理♂性♂愉♂悦♂一 ...

  2. Oracle自定义类型在C#中调用示例

    1.C#代码: 1)using Oracle.DataAccess.Types; using System; using System.Collections.Generic; using Syste ...

  3. JS学习笔记 - 面向对象

    类.对象类:模子对象:产品(成品) 蛋糕(对象) 模子(类) Array 类 arr 对象 Array.push(); 错 arr.push(); 对 new arr(); 错 原型prototype ...

  4. linux下设置密码复杂度限制,怎么设置?

    在linux,设置密码复杂度的方法有几个1. 一个是在/etc/login.defs文件,里面几个选项PASS_MAX_DAYS 90 #密码最长过期天数PASS_MIN_DAYS 80 #密码最小过 ...

  5. Oracle中暂时表空间的清理

    作者:iamlaosong Oracle暂时表空间主要用来做查询和存放一些缓冲区数据. 暂时表空间消耗的主要原因是须要对查询的中间结果进行排序.暂时表空间的主要作用: 索引create或rebuild ...

  6. UvaLive 6663 Count the Regions 离散化+DFS

    链接:http://vjudge.net/problem/viewProblem.action?id=49408 题意:在平面内给出若干个矩形,求出它们能将整个平面分成多少份. 思路:刚開始一眼看到认 ...

  7. 使用GDB进行嵌入式远程调试

    PC主机:Ubuntu 10.4 目标板:TQ2440开发板,linux内核2.6.30 NOTE:为了使用gdb进行调试,强烈建议使用nfs服务,否则调试会非常麻烦. 使用nfs服务可以参考:S3C ...

  8. arm-linux-gcc: Command not found

    老是提示arm-linux-gcc找不到,但是确实是装好了,其实是权限的问题,Ubuntu没有root权限,刚开始用碰到很多麻烦,查了好多资料,终于把arm-linux-gcc: Command no ...

  9. 【例题5-1 UVA 10474 】Where is the Marble?

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 排序 用lower_bound找就可以了. ->lower_bound,如果里面所有的数字都比x小,那么它的返回值会越界! [ ...

  10. 【Android开源框架】使用andbase开发框架实现绘制折线图

    在Android中,当有绘制折线图的需求时.大多数人使用的AChartEngine,来进行折线图的绘制.AChartEngine图表引擎确实能够实现折线图的功能.除此之外,我们还能够使用andbase ...