洛谷 P1039侦探推理
- /*
- 枚举罪犯和星期几,那么所有人说的话是真是假一目了然。
- 首先一个人不能既说真话又说假话。
- 即:
- I am guilty.
- I am not guilty.
- 因为非真即假,所以直接判断impossible.
- map<string,int>表示名字对应的id name[i]表示id为i的人对应的人名。
- kp[i][j]表示第i个人认为第j个人是不是罪犯。0/-1/1,表示不是,没说,是
- kd[i][j]表示第i个人认为今天是星期j么?0/-1/1表示 不认为、没说、认为
- impossible的情况之一即kp[i][j]=1后又要赋值为 kp[i][j]=0;
- 假设罪犯是t(id),今天是d;//现在已经没有人既说真话又说假话了。
- 现在人有三类:
- 说真话 说假话 说废话
- 如何判断一个人说真话还是说假话。
- 假设
- Amy:
- ①I am guilty. (如果Amy不是t,那么这人说假话;如果Amy是t,那么这个人一定说真话)
- ②I am not guilty. (如果他是t,那么这人说假话;如果不是t,那么它一定说真话)
- ③XXX is guilty. (XXX是t,真话;XXX不是t,假话)
- ④XXX is not guilty. (XXX是t,假话;XXX不是t,真话)
- ⑤Today is x (x是d,真话;x不是d,假话)。
- 所以,一个人只要不说废话,那么他说真话还是说假话都知道了
- say[i]=0/-1/1表示id为i的人说假话,不确定,说真话
- 若一个人说的是假话,那么他说的假话的反面就是真话。
- 下面的句子是可以通过这个人说的是假话判断出来的。
- ①他不是罪犯
- ②他是罪犯
- ③XXX 不是罪犯
- ④XXX 是罪犯
- 这时需要另辟数组来标记。
- p[i]=0/-1/1分别表示这个人不是罪犯、不确定、是罪犯。
- d[i]=0/-1/1分别表示今天不是星期i、不确定是不是星期i、今天是星期i。
- 这时矛盾出现了
- 甲:
- A is guilty.
- t is not guilty.
- 乙:
- A is not guilty.
- t is not guilty.
- 此时甲、乙二人都不认为t是罪犯,那么他们说的都是假话了
- 根据甲来说:A 应该不是罪犯。
- 根据乙来说:A 应该是罪犯。
- 出现了矛盾,这个情况应该pass了。
- 即p[i]赋值为0后,又要被赋值为1。d数组同样。
- 所以p[]、d[]数组只能从不确定状态赋值为确定状态,不能从一个
- 确定状态标记为另一个确定状态。
- 如果说谎话的人<=n&&说谎的人+说废话的人>=n,那么满足始终有n个人说假话了。
- 在看p[i]数组,如果有人标记了不确定是不是罪犯,那么这个情况就是不确定罪犯了。
- 所以最后
- 1)若唯一能确定罪犯,输出。
- 2)不能唯一确定,有多解的情况 cannot determine。
- 3)所有举例的情况都有矛盾,都被pass了,impossible.
下面的代码windows下是A的...洛谷A不了....占个坑。
- #include<iostream>
- #include<map>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- int m,n,p,ans;
- int say[];
- int kp[][],kd[][];
- string name[];
- string a[],b[],c[];
- map<string,int>k;
- void read()
- {
- for(int i=;i<=m;i++)
- {
- string s;
- cin>>s; name[i]=s;
- s+=":"; k[s]=i;
- }
- // char ch=getchar();
- // while(ch==10)ch=getchar();getchar();
- for(int i=;i<=p;i++)
- {
- cin>>a[i]>>b[i];
- if(b[i]!="Today"&&c[i]!=" is guilty."&&c[i]!=" is not guilty.")b[i]+=":";//***
- getline(cin,c[i]);
- }
- }
- void pre_deal()
- {
- int flag=;
- memset(kp,-,sizeof(kp));
- memset(kd,-,sizeof(kd));
- for(int i=;i<=p;i++)
- {
- int id=k[a[i]];
- if(c[i]==" am guilty.") {if(!kp[id][id]) flag=;else kp[id][id]=;}
- if(c[i]==" am not guilty."){if(kp[id][id]==) flag=;else kp[id][id]=;}
- if(c[i]==" is guilty.") {int h=k[b[i]];if(!kp[id][h]) flag=;else kp[id][h]=;}
- if(c[i]==" is not guilty."){int h=k[b[i]];if(kp[id][h]==) flag=;else kp[id][h]=;}
- if(b[i]=="Today")
- {
- if(c[i]==" is Monday.") kd[id][]=;
- if(c[i]==" is Tuesday.") kd[id][]=;
- if(c[i]==" is Wednesday.") kd[id][]=;
- if(c[i]==" is Thursday.") kd[id][]=;
- if(c[i]==" is Friday.") kd[id][]=;
- if(c[i]==" is Saturday.") kd[id][]=;
- if(c[i]==" is Sunday.") kd[id][]=;
- }
- if(flag){printf("Impossible\n");exit();} //***
- }
- }
- bool check(int x,int y)
- {
- memset(say,-,sizeof(say));
- for(int i=;i<=m;i++)
- {
- for(int j=;j<=m;j++)
- {
- if((kp[i][j]==&&j!=x)||(kp[i][j]==&&j==x))
- {
- if(say[i]==) return false;
- say[i]=;
- }
- if((kp[i][j]==&&j==x)||(kp[i][j]==&&j!=x))
- {
- if(say[i]==) return false;
- say[i]=true;
- }
- }
- for(int q=;q<=;q++)
- {
- if(kd[i][q]==&&q!=y)
- {
- if(say[i]==) return false;
- say[i]=;
- }
- if(kd[i][q]==&&q==y)
- {
- if(say[i]==) return false;
- say[i]=true;
- }
- }
- }
- return true;
- }
- int main()
- {
- scanf("%d%d%d",&m,&n,&p);//m同学数,n始终说谎的人数,p为证言总数。
- read();
- pre_deal();
- for(int i=;i<=m;i++)
- {
- for(int j=;j<=;j++)
- {
- int saylie=,notjudge=;
- if(check(i,j))
- {
- for(int p=;p<=m;p++)
- {
- if(say[p]==-) notjudge++;
- if(say[p]==) saylie++;
- }
- if(saylie<=n&¬judge+saylie>=n)
- {
- if(ans&&i!=ans)
- {
- printf("Cannot Determine\n");
- exit();
- }
- ans=i;
- }
- }
- }
- }
- if(ans) cout<<name[ans]<<endl;
- else printf("Impossible\n");
- return ;
- }
洛谷 P1039侦探推理的更多相关文章
- 洛谷P1039 侦探推理(模拟)
侦探推理 题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情 ...
- [NOIP2003] 提高组 洛谷P1039 侦探推理
题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...
- 洛谷 P1039 侦探推理
题目:https://www.luogu.org/problemnew/show/P1039 分析: 这道题是一道有技术含量的模拟,我们主要是不要让计算机向人一样思考,只需要让他穷举变化的星期几和当罪 ...
- 洛谷P1039侦探推理题解
#include<cstdio> #include<cstring> #include<string> #include<iostream> using ...
- Luogu P1039 侦探推理(模拟+枚举)
P1039 侦探推理 题意 题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯 ...
- 【洛谷P1039】侦探推理
侦探推理 题目链接 这是一道恶心至极的模拟题 我们可以枚举罪犯是谁,今天是星期几,从而判断每个人说的话是真是假 若每个人说的话的真假一致,且说谎话的人数<=k且说真话的人数<=m-k,就是 ...
- P1039 侦探推理(洛谷)
昨天做了一个非常神奇的题,告诉我们做题之前一定要好好检测评测姬! 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先 ...
- P1039 侦探推理
题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...
- LUOGU P1039 侦探推理 (字符串+模拟)
传送门 解题思路 一道%你神题,\(string\)好强大啊..首先枚举一个周几,再枚举一个罪犯是谁,然后判断的时候就是枚举所有人说的话.定义\(fAKe[i]\)表示第\(i\)个人说的是真话还是假 ...
随机推荐
- nats
NATS is a family of open source products that are tightly integrated but can be deployed independent ...
- 深入理解jvm--Java中init和clinit区别完全解析(转)
转自:http://blog.csdn.net/u013309870/article/details/72975536 init和clinit区别 ①init和clinit方法执行时机不同 init是 ...
- CSS3之嵌入Web字体
之前如果想在自己的网站使用某些好看的字体,总是迫不得已得在PS里先把字体图片做好.虽然这样做也能达到我们想要的效果,但是这样就增加了HTTP请求(如果在多处使用的话),即使合并所有图片,也不好管理,灵 ...
- ESXi主机遗忘密码重置密码
ESXi版本:6.0.0 VMware-VMvisor-Installer-6.0.0.update02-3620759.x86_64-Dell_Customized-A00.iso 使用和服务器系统 ...
- 【建项目】eclipse maven建立多模块工程
在工作的时候,大多时候都是用Maven来管理项目,可是一般我们都知道怎么用maven管理工程,却不知道通过Maven自己来建立多模块工程.于是自己抽时间,在网上找些资料,做了起来. 建立简单的Mave ...
- SpringMVC整个执行流程
在SSM (或SSH) 框架整合使用后,基本骨架看上去还是MVC的结构. MyBatis整合一些数据封装方法节省了DAO层的代码量, Spring提供了AOP,IoC( DI 具体实现 ). 而Spr ...
- Tensorflow1.5.0+cuda9.0+cudnn7.0+gtx1080+ubuntu16.04
目录 Tensorflow1.5.0+cuda9.0+cudnn7.0+gtx1080+ubuntu16.04 0. 前记 1. 环境说明 2. 安装GTX1080显卡驱动 3. CUDA 9.0安装 ...
- spring boot2 基于百度云apiface实现人脸检测与认证2
接上一篇,上篇只实现了人脸的认证,接下来实现人脸的检测. 原理介绍: 把摄像头抓拍的图像上传到服务器,服务器把图像上传到百度云,百度云返回识别出的人脸的数量和位置,前端根据服务端的返回,在图像中画出人 ...
- InfiniBand 与Intel Omni-Path Architecture
Intel Omni-Path Architecture (OPA) 是一种与InfiniBand相似的网络架构 可以用来避免以下PCI总线一些缺陷: 1.由于采用了基于总线的共享传输模式,在PCI总 ...
- 《WAP》第一次作业:团队亮相
一.队名:WAP! 二.团队成员组长 组员 : 201571030302/杜有海 201571030327/乌勒扎 201571030304/郝明宇 201571030318/马麒 组长: 20157 ...