题目描述

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

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

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

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

输入输出格式

输入格式:

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

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

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

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

输出格式:

如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 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

惊天大模拟

惊天码农题

首先需要花式截取出每个人的信息,然后需要记录以下信息:

  每个人说的日期

  每个人说自己是不是罪犯

  每个人说谁是罪犯

  每个人说谁不是罪犯

枚举日期和嫌疑犯,进行判断:

  记说谎人数为tmp,可疑人数为cnt(可疑人数指没有说过真话,也没有说过假话的人数),题目限制说谎人数为m

  若tmp>m,说明当前枚举的情况不成立。

  若tmp+cnt<m,说明已知说谎的人和可能说谎的人加起来都不够目标值,不成立。

  除此之外的情况下,当前枚举到的嫌疑犯可能是罪犯。

若可能是罪犯的人数大于1人,cannot determine

 /*By SilverN*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
string pp[]={"am guilty","am not guilty","is guilty.","is not guilty."};
string week[]={" ","is Monday","is Tuesday","is Wednesday","is Thursday","is Friday","is Saturday","is Sunday"};
//
int n,m,p;
//
string name[];
map<string,int>mp;
//人名
string s[];
struct person{
bool is;//是否确定是罪犯
int wk;//每个人对天气的判断
int guil[];//每个人对其他人身份的判断
vector<int>g_list,nog_list;//每个人指认的罪犯
}a[];
//身份信息
bool posi[];
int work(int day,int uso){
int cnt=,tmp=;//不确定的人,确定的凶手 for(int i=;i<=n;i++){
bool f_true=,f_false=;
if(a[i].is || (a[i].wk && a[i].wk!=day)){//天气说错
f_false=;
}
if(a[i].guil[uso]==-){//说罪犯不是罪犯
f_false=;
}
if(a[i].guil[uso]==)f_true=;//说罪犯是罪犯
if(i!=uso && a[i].guil[i]==){//不是罪犯说自己是罪犯
f_false=;
}
for(int j=;j<a[i].g_list.size();j++)if(a[i].g_list[j]!=uso){//说不是罪犯的人是罪犯
f_false=;
}
for(int j=;j<a[i].nog_list.size();j++)if(a[i].nog_list[j]!=uso){//说不是罪犯的人不是罪犯
f_true=;
}
if(a[i].wk==day)f_true=;
if(i==uso && a[i].guil[uso]==) f_true=;//凶手说自己是凶手
if(i!=uso && a[i].guil[i]==-) f_true=;//不是凶手说自己不是凶手
if(f_true && f_false)return ;//不合法
if(f_false)tmp++;
if(!f_true && !f_false)cnt++;//不确定的人
}
// printf("day:%d uso:%d cnt:%d tmp:%d\n",day,uso,cnt,tmp); if(tmp>m)return ;
if(tmp+cnt<m)return ;
return ;
}
int target=;
void solve(){
int tmp=;
int i,j;
for(i=;i<=;i++)//枚举日期
for(j=;j<=n;j++)//枚举凶手
{
if(posi[j])continue;
if(work(i,j)){
++tmp;
posi[j]=;
if(tmp>=){
printf("Cannot Determine\n");
return;
}
target=j;
}
}
if(!target)printf("Impossible\n");
cout<<name[target]<<endl;
return;
}
//
int main(){
scanf("%d%d%d",&n,&m,&p);//总人数 说谎人数 证言数
int i,j;
for(i=;i<=n;i++){
cin>>name[i];
mp[name[i]]=i;
}
for(i=;i<=p;++i){
cin>>s[i];
// cout<<"test"<<s[i]<<endl;
s[i]=s[i].substr(,s[i].find(':'));
// cout<<"finn"<<endl;
int id=mp[s[i]];
getchar();
getline(cin,s[i]);
// cout<<"now-"<<s[i]<<endl;
//判断
if(s[i][]=='I'){
if(s[i].find(pp[])!=-){//I am guilty
a[id].guil[id]=; continue;
}
else if(s[i].find(pp[])!=-){//I am not guilty
a[id].guil[id]=-; continue;
}
}
else{
int tmp=;
tmp=s[i].find(pp[]);
if(tmp!=-){//is guilty
// printf("is guilty: %d\n",tmp);
s[i]=s[i].substr(,tmp-);
// printf("mp:%d\n",mp[s[i]]);
// cout<<"test: "<<s[i]<<"eld"<<endl;
a[id].guil[mp[s[i]]]=;
a[id].g_list.push_back(mp[s[i]]);
continue;
}
tmp=s[i].find(pp[]);
if(tmp!=-){//is not guilty
s[i]=s[i].substr(,tmp-);
// printf("mp:%d\n",mp[s[i]]);
// cout<<"test: "<<s[i]<<"eld"<<endl;
a[id].guil[mp[s[i]]]=-;
a[id].nog_list.push_back(mp[s[i]]);
continue;
}
for(j=;j<=;j++)//天气判定
{
tmp=s[i].find(week[j]);
if(tmp!=-){
if(!a[id].wk)
a[id].wk=j;
else a[id].is=;//天气前后矛盾,肯定是骗子
break;
}
}
}
//
}
//结束读入
/*
for(i=1;i<=n;i++){
printf("info of %d:\n",i);
cout<<name[i]<<endl; printf("wk: %d\n",a[i].wk);
printf("self: %d\n",a[i].guil[i]);
for(j=0;j<a[i].g_list.size();j++)printf("%d ",a[i].g_list[j]);
printf("\n");
for(j=0;j<a[i].nog_list.size();j++)printf("%d ",a[i].nog_list[j]);
printf("\n");
}*/
//
solve(); return ;
}

[NOIP2003] 提高组 洛谷P1039 侦探推理的更多相关文章

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

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

  2. 洛谷 P1039侦探推理

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

  3. 洛谷 P1039 侦探推理

    题目:https://www.luogu.org/problemnew/show/P1039 分析: 这道题是一道有技术含量的模拟,我们主要是不要让计算机向人一样思考,只需要让他穷举变化的星期几和当罪 ...

  4. [NOIP2003] 提高组 洛谷P1041 传染病控制

    题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带 ...

  5. [NOIP2003] 提高组 洛谷P1040 加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  6. [NOIP2003] 提高组 洛谷P1038 神经网络

    题目背景 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款风险评估等诸多领域有广泛的应用.对神经网络的研究一直是当今 ...

  7. 洛谷P1039侦探推理题解

    #include<cstdio> #include<cstring> #include<string> #include<iostream> using ...

  8. [NOIP2015] 提高组 洛谷P2615 神奇的幻方

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  9. [NOIP2014] 提高组 洛谷P2038 无线网络发射器选址

    题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...

随机推荐

  1. 用户控件引用Entity Framework

    背景: 今天在做软件的时候,出现了问题,我在项目里面添加了Entity Framework,在form的代码里引用没有问题,在userControl里引用就出了问题. 我检查app.config文件 ...

  2. 解决spring boot websocket

    在网上找的demo写了一个小例子,本地开发测试都很正常,但是部署在tomcat就各种坑 1.MyWebSocket不要用spring 注解标注 2.main方法对应的类继承SpringBootServ ...

  3. JSP自定义标签开发步骤

    自定义的标签库一.基本概念: 1.标签(Tag): 标签,通常也成为动作,是一组按照XML语法格式编写的代码片段,在JSP中,用来封装在页面中可重复利用的逻辑,通过标签可以使JSP网页变得简洁并且易于 ...

  4. 消息中间件与RPC的区别

    消息中间件和消息通信与RPC各自具有怎样的优势,如何互补消息中间件主要实现的是异步.弹性消息以及队列,弹性消息有时可以借助于外存从而一定程度上可以实现峰值缓存,有效均衡服务器端压力,同时消息可以进行一 ...

  5. SQLite – GLOB子句

    SQLite – GLOB子句 .与LIKE不同,GLOB是大小写敏感的,它遵循语法的UNIX指定以下通配符. The asterisk sign (*) The question mark (?) ...

  6. (转)Spring的bean管理(注解方式)

    http://blog.csdn.net/yerenyuan_pku/article/details/69663779 Spring的bean管理(注解方式) 注解:代码中的特殊标记,注解可以使用在类 ...

  7. 总结vue2.0 配置的实例方法

    总结vue2.0 配置的实例方法 http://www.php.cn/js-tutorial-369603.html

  8. mkdir touch vim

    vim和touch都用于新建文件 mkdir用于新建文件夹

  9. 暑假集训 || LCA && RMQ

    LCA定义为对于一颗树 树上两个点的最近公共祖先 一.Tarjan求LCA(离线方法 https://blog.csdn.net/lw277232240/article/details/7701751 ...

  10. JavaScript递归简单实现个对象深拷贝

    JavaScript中对象的深拷贝来说一直都算比较恶心 毕竟没有什么api能直接全拷贝了 得自己便利写  最近在项目中需要深拷贝 自己简单封了个方法 话不多说 直接上码 <!DOCTYPE ht ...