/*
枚举罪犯和星期几,那么所有人说的话是真是假一目了然。
首先一个人不能既说真话又说假话。
即:
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&&notjudge+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侦探推理的更多相关文章

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

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

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

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

  3. 洛谷 P1039 侦探推理

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

  4. 洛谷P1039侦探推理题解

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

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

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

  6. 【洛谷P1039】侦探推理

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

  7. P1039 侦探推理(洛谷)

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

  8. P1039 侦探推理

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

  9. LUOGU P1039 侦探推理 (字符串+模拟)

    传送门 解题思路 一道%你神题,\(string\)好强大啊..首先枚举一个周几,再枚举一个罪犯是谁,然后判断的时候就是枚举所有人说的话.定义\(fAKe[i]\)表示第\(i\)个人说的是真话还是假 ...

随机推荐

  1. java提升路线

    转载自:http://blog.csdn.net/a151296/article/details/43658853 作为一名即将从事java开发的应届毕业生,迷茫中,转载此篇文章,作为提升自己的学习方 ...

  2. laravel 项目部署注意事项

    1.'Failed to open stream: Permission denied' error - Laravel Laravel >= 5.4 php artisan cache:cle ...

  3. HttpClient4.x 使用cookie保持会话

    HttpClient4.x可以自带维持会话功能,只要使用同一个HttpClient且未关闭连接,则可以使用相同会话来访问其他要求登录验证的服务(见TestLogin()方法中的“执行get请求”部分) ...

  4. linux及安全《Linux内核设计与实现》第二章——20135227黄晓妍

    第二章:从内核出发 2.1获取源代码 2.1.1使用git Git:内核开发者们用来管理Linux内核源代码的控制系统. 我们使用git来下载和管理Linux源代码. 2.1.2安装内核源代码(如果使 ...

  5. cuda8.0 出错:/usr/bin/ld: 找不到 -lGL【转】

    本文转自:https://blog.csdn.net/u010159842/article/details/56833030 最近在学习深度学习,在搭建CUDA8.0的时候,出现一个非常不好的问题: ...

  6. [CF580D]Kefa and Dishes

    题意翻译 kefa进入了一家餐厅,这家餐厅中有n个菜(0<n<=18),kefa对第i个菜的满意度为ai(0<=ai<=10^9),并且对于这n个菜有k个规则,如果kefa在吃 ...

  7. 斜率优化DP学习笔记

    先摆上学习的文章: orzzz:斜率优化dp学习 Accept:斜率优化DP 感谢dalao们的讲解,还是十分清晰的 斜率优化$DP$的本质是,通过转移的一些性质,避免枚举地得到最优转移 经典题:HD ...

  8. UVa 11538 象棋中的皇后

    https://vjudge.net/problem/UVA-11538 题意: n×m的棋盘,有多少种方法放置两个相互攻击的皇后? 思路: 这两个皇后互相攻击的方式只有3种,在同一行,在同一列,或在 ...

  9. 使用 switch 对值进行分支

    与处理 TRUE 和 FALSE 条件的 if 相比,switch 语句则是用来处理数字或者字符串,并根据输入返回某个分支.假设输入一个整数 n,switch 返回从第 1 个参数开始的第 n 个参数 ...

  10. JQuery中width和JS中JS中关于clientWidth offsetWidth scrollWidth 等的含义

    JQuery中: width()方法用于获得元素宽度: innerWidth()方法用于获得包括内边界(padding)的元素宽度: outerWidth()方法用于获得包括内边界(padding)和 ...