【NOIP 2003提高】侦探推理 模拟
来源:互联网 发布:色诺芬经济金融数据库 编辑:程序博客网 时间:2024/05/01 07:03
题目描述
明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:
证词中出现的其他话,都不列入逻辑推理的内容。
明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。
现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!
数据范围
1≤M≤20
1≤N≤M
1≤P≤100
样例输入
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
解题思路
枚举凶手与日期判断即可。注意如果一个人说的全是被忽略的话,也可以把他当做说谎的人。
代码
#include <bits/stdc++.h>using namespace std;inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}inline string Getname(){string s="";char ch=getchar();while(!isalpha(ch))ch=getchar();while(isalpha(ch))s+=ch,ch=getchar();return s;}inline string Getline(){ string s=""; char ch=getchar(); while(!isalpha(ch)) ch=getchar(); while(ch!='\n'){ s+=ch; ch=getchar(); if(ch==-1)break;//不知道为什么,交我们学校OJ必须要加这一句话。。。不然读入卡死 } return s;}inline string Splitname(string s){string ret="";for(int i=0;s[i]!=':';i++)ret+=s[i];return ret;}inline string Splitword(string s){string ret="";int p=0;while(s[p]!=':')p++;for(p++;p<s.length();p++)ret+=s[p];return ret;}string name[25];string w[8]={""," Today is Monday."," Today is Tuesday."," Today is Wednesday."," Today is Thursday."," Today is Friday."," Today is Saturday."," Today is Sunday.",};string e[2]={" I am guilty."," I am not guilty."};string s[105];map<string,int>Map;int vis[105],fail;int Check1(string s){ if(s.length()<13)return 0; string tmp=s.substr(s.length()-11,11); if(tmp!=" is guilty.")return false; tmp=s.substr(1,s.length()-12); return Map[tmp];}int Check2(string s){ if(s.length()<17)return 0; string tmp=s.substr(s.length()-15,15); if(tmp!=" is not guilty.")return false; tmp=s.substr(1,s.length()-16); return Map[tmp];}void Change(int x,bool t){ if(t&&vis[x]==2)fail=1; if(!t&&vis[x]==1)fail=1; if(t)vis[x]=1; if(!t)vis[x]=2;}int main(){ int m=Getint(),n=Getint(),p=Getint(),Ans=0; for(int i=1;i<=m;i++)Map[name[i]=Getname()]=i; for(int i=1;i<=p;i++)s[i]=Getline(); for(int i=1;i<=m;i++){ for(int j=1;j<=7;j++){ fail=0; memset(vis,0,sizeof(vis)); int t,tot=0; for(int k=1;k<=p;k++){ string Name=Splitname(s[k]); string word=Splitword(s[k]); for(int l=1;l<=7;l++)if(word==w[l])Change(Map[Name],l==j); if(word==e[0])Change(Map[Name],i==Map[Name]); if(word==e[1])Change(Map[Name],i!=Map[Name]); t=Check1(word); if(t)Change(Map[Name],t==i); t=Check2(word); if(t)Change(Map[Name],t!=i); } for(int k=1;k<=m;k++) if(vis[k]==2) tot++; int tot2=0; for(int k=1;k<=m;k++) if(!vis[k]) tot2++; if(fail||tot>n||tot+tot2<n)continue; if(Ans!=i&&Ans){ cout<<"Cannot Determine\n"; exit(0); } Ans=i; } } if(!Ans)cout<<"Impossible\n"; else cout<<name[Ans]; return 0;}
0 0
- 【NOIP 2003提高】侦探推理 模拟
- vijos1106侦探推理&&Noip提高组2003
- [NOIP提高组2003]侦探推理
- Noip 2003T2 侦探推理
- NOIP 2003 侦探原理 大模拟+枚举
- noip2003 侦探推理 终极模拟
- 侦探推理
- 侦探推理
- [NOIP模拟][数学推理]Math
- vijos 1106 & NOIP2003 提高组 侦探推理 题解
- 侦探推理小故事
- Codevs 侦探推理
- 侦探推理 (NOIP2003)
- NOIP2003 侦探推理
- 洛谷 P1039 侦探推理
- noip2003侦探推理详解
- 【b302】侦探推理
- NOIP2003 侦探推理 详解
- 数据结构复习之用两个栈模拟队列操作
- Linux下的C文件在windows下中文显示乱码解决
- Android快速开发工具集合——YUtils
- 【OpenCV图像处理】十四、图像金字塔
- 算法训练 P1101
- 【NOIP 2003提高】侦探推理 模拟
- Qt自适应大小显示图片,添加菜单
- java静态代理和动态代理
- matplotlib画图内存爆表
- [DPDK编程手册]5Mempool库
- hdoj杭电问题分类
- 图片上传
- Mat属性type,depth,step
- eclipse编辑默认的jsp文件