[NOIP2003提高组]侦探推理
题目:洛谷P1039、Vijos P1106、codevs1089。
题目大意:给你一系列证词,要你求出谁是凶手。具体题目见原题。
解题思路:我们枚举犯人和星期,一个一个进行判断。如果成功则记录答案,如果成功且以前已经记录了答案,则说明有多个凶手,输出“Cannot Determine”,如果最后没有答案,则输出“Impossible”。主要是字符串的处理。其他细节见代码注释。
然而我的代码用了getline,在Linux下最后会读入Windows的换行符!!这个问题我找了半天!!后来我把代码稍微改了一下(代码第85~87行的处理),使其兼容Linux和Windows(洛谷和codevs是Linux的,Vijos是Windows的)。
C++ Code:
#include<iostream>
#include<cstring>
#include<string>
#include<map>
#include<cstdlib>
using namespace std;
const string days[]={
"Today is Monday.",
"Today is Tuesday.",
"Today is Wednesday.",
"Today is Thursday.",
"Today is Friday.",
"Today is Saturday.",
"Today is Sunday."
};
map<string,int>num;//记录编号
string name[22];//名字
int n,m,p,cnt,ans,TF[102],T,F;//T表示当前说真话的人数,F表示当前说假话的人数,TF[i]表示i说真话还是假话
struct word{//id是说这句话的人的编号,st是说的话
int id;
string st;
}f[102];
string s;
bool pdTF(int id,bool b){//判断是否有冲突,返回1表示有冲突
if(TF[id]==-1){
TF[id]=b;
if(b)++T;else ++F;
}else{
if(TF[id]==b)return 0;else return 1;
}
if(F>m||T>n-m)return 1;
return 0;
}
void Judge(int Xs,string day){//测试,若有冲突则直接跳出来
memset(TF,-1,sizeof(TF));
T=F=0;
for(int i=1;i<=p;++i){
int pos;
pos=f[i].st.find("I am guilty.");
if(~pos){
if(pdTF(f[i].id,f[i].id==Xs))return;
}
pos=f[i].st.find("I am not guilty.");
if(~pos){
if(pdTF(f[i].id,f[i].id!=Xs))return;
}
pos=f[i].st.find(" is guilty.");
if(~pos){
string now=f[i].st;
now.erase(pos,11);
int id=num[now];
if(pdTF(f[i].id,id==Xs))return;
}
pos=f[i].st.find(" is not guilty.");
if(~pos){
string now=f[i].st;
now.erase(pos,15);
int id=num[now];
if(pdTF(f[i].id,id!=Xs))return;
}
pos=f[i].st.find("Today is ");
if(~pos){
if(pdTF(f[i].id,f[i].st==day))return;
}
}
/*全部语句检测完毕,没有冲突*/
if(ans&&ans!=Xs){//已有答案但不是当前凶手,说明有多个凶手
cout<<"Cannot Determine"<<endl;
exit(0);//直接结束程序
}
ans=Xs;
}
int main(){
cin>>n>>m>>p;
for(int i=1;i<=n;++i){
cin>>name[i];
num[name[i]]=i;
}
for(int i=1;i<=p;++i){
cin>>s;
s.erase(s.length()-1,1);
f[i].id=num[s];
getline(cin,f[i].st);
f[i].st.erase(0,1);
char ch=f[i].st[f[i].st.length()-1];
if(ch=='\n'||ch=='\r'||ch==' ')
f[i].st.erase(f[i].st.length()-1,1);
}
ans=0;
for(int i=1;i<=n;++i)
for(int j=0;j<7;++j)
Judge(i,days[j]);
if(!ans)//没有搜到凶手
cout<<"Impossible"<<endl;else
cout<<name[ans]<<endl;
return 0;
}
[NOIP2003提高组]侦探推理的更多相关文章
- noip2003提高组题解
这一年的前三题虽然难度不高,但是第二题极为繁琐,想在考场上用较短的时间拿到第二题的分数难上加难.所以必须要调整策略,争取拿其他三题的分数.第四题是比较普通的搜索题,分数比较好拿,但是很容易想成树形DP ...
- [NOIP2003] 提高组 洛谷P1039 侦探推理
题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...
- 题解【洛谷P1038/CJOJ1707】[NOIP2003提高组]神经网络
[NOIP2003]神经网络 Description 问题背景:人工神经网络( Artificial Neural Network )是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款 ...
- 【NOIP2003提高组】加分二叉树
https://www.luogu.org/problem/show?pid=1040 令f(i,j)表示[i,j]的二叉树中最高的分数.枚举k为根,状转方程:f(i,j)=max{f(i,k-1)* ...
- [NOIp2003提高组]神经网络
OJ题号:洛谷1038 思路:拓扑排序,注意细节.1.题目中求和运算$C_i=\displaystyle{\sum_{(j,i)\in E}W_{ji}C_j-U_i}$中$U_i$在求和运算外,只要 ...
- [NOIP2003] 提高组 洛谷P1041 传染病控制
题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带 ...
- [NOIP2003] 提高组 洛谷P1040 加分二叉树
题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...
- [NOIP2003] 提高组 洛谷P1038 神经网络
题目背景 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款风险评估等诸多领域有广泛的应用.对神经网络的研究一直是当今 ...
- NOIP2003[提高组] 加分二叉树 题解
题意 给出一个有n个节点的二叉树的中序遍历,以当前节点为根的树的分数等于左节点分数* 右节点分数+根节点分数,叶子节点的分数等于它本身,求最大分数,以及分数最大的树的先序遍历 一道区间dp题,因为要求 ...
随机推荐
- Unity 组件的增、查、禁、删 代码书写
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { // Use this for initialization ...
- Pyhton学习——Day24
# #面向对象设计:# def dog(name,gender,type):# def jiao(dog):# print('One Dog[%s],wfwfwf'%dog['name'])# def ...
- 移动端和pc端的判断,不同端做不同的处理
1.通过js判段是pc端还是移动端 function browserRedirect() { var type = ""; var sUserAgent = navigator.u ...
- java中的string trim具体有什么用处。。。
去掉字符串首尾空格 防止不必要的空格导致错误public class test{ public static void main(String[] args) { String str = " ...
- MHA 主从切换过程及日志分析
本文主要在MHA 切换日志的角度分析MHA切换的过.MHA故障切换过程如下图所示 第一部分:开启MHA 监控 通过分析日志,得到以下步骤: 1.读取MHA manager 节点的配置文件,并检查配置文 ...
- Linux系统下安装 rpm 软件和源代码 软件包
RPM 安装方式 RPM是一个包安装管理软件,我们可以使用这个工具安装 .rpm 类型的软件.Linux的rpm包很多都能在光盘的Packages 包中找得到.首先挂载一下光盘,查看Packages中 ...
- 用 JavaScript 实现简单拼图游戏
本篇主要讲解,如何利用原生的 JavaScript 来实现一个简单的拼图小游戏. 线上体验地址:拼图 一.游戏的基础逻辑 想用一门语言来开发游戏,必须先了解如何使用这门语言来实现一些基础逻辑,比如图像 ...
- webstorm注册码注册
最近jetbrains公司更新软件总是特别的快,很多私人搭建的server服务也失效了,现出一个能够永久破解的方法,非常简单,只需要2步就完成. 第一步 复制下方activation code,直接粘 ...
- windows关于定时执行的php脚本
根据业务需求,需要服务器每天定时执行一些脚本,如后台提交数据,定时处理数据库等. 最初的思路是在某个控制器里写好方法,加入code验证,定期的用计划任务去访问.由于window计划任务这方面比较low ...
- 关于nodejs的线程模型可以看这篇文章
虽然还是有一些没有讲全,但是整体还是讲的很不错的. http://www.ruanyifeng.com/blog/2014/10/event-loop.html