题目:洛谷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提高组]侦探推理的更多相关文章

  1. noip2003提高组题解

    这一年的前三题虽然难度不高,但是第二题极为繁琐,想在考场上用较短的时间拿到第二题的分数难上加难.所以必须要调整策略,争取拿其他三题的分数.第四题是比较普通的搜索题,分数比较好拿,但是很容易想成树形DP ...

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

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

  3. 题解【洛谷P1038/CJOJ1707】[NOIP2003提高组]神经网络

    [NOIP2003]神经网络 Description 问题背景:人工神经网络( Artificial Neural Network )是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款 ...

  4. 【NOIP2003提高组】加分二叉树

    https://www.luogu.org/problem/show?pid=1040 令f(i,j)表示[i,j]的二叉树中最高的分数.枚举k为根,状转方程:f(i,j)=max{f(i,k-1)* ...

  5. [NOIp2003提高组]神经网络

    OJ题号:洛谷1038 思路:拓扑排序,注意细节.1.题目中求和运算$C_i=\displaystyle{\sum_{(j,i)\in E}W_{ji}C_j-U_i}$中$U_i$在求和运算外,只要 ...

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

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

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

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

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

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

  9. NOIP2003[提高组] 加分二叉树 题解

    题意 给出一个有n个节点的二叉树的中序遍历,以当前节点为根的树的分数等于左节点分数* 右节点分数+根节点分数,叶子节点的分数等于它本身,求最大分数,以及分数最大的树的先序遍历 一道区间dp题,因为要求 ...

随机推荐

  1. Unity 组件的增、查、禁、删 代码书写

    using UnityEngine; public class NewBehaviourScript : MonoBehaviour { // Use this for initialization ...

  2. Pyhton学习——Day24

    # #面向对象设计:# def dog(name,gender,type):# def jiao(dog):# print('One Dog[%s],wfwfwf'%dog['name'])# def ...

  3. 移动端和pc端的判断,不同端做不同的处理

    1.通过js判段是pc端还是移动端 function browserRedirect() { var type = ""; var sUserAgent = navigator.u ...

  4. java中的string trim具体有什么用处。。。

    去掉字符串首尾空格 防止不必要的空格导致错误public class test{ public static void main(String[] args) { String str = " ...

  5. MHA 主从切换过程及日志分析

    本文主要在MHA 切换日志的角度分析MHA切换的过.MHA故障切换过程如下图所示 第一部分:开启MHA 监控 通过分析日志,得到以下步骤: 1.读取MHA manager 节点的配置文件,并检查配置文 ...

  6. Linux系统下安装 rpm 软件和源代码 软件包

    RPM 安装方式 RPM是一个包安装管理软件,我们可以使用这个工具安装 .rpm 类型的软件.Linux的rpm包很多都能在光盘的Packages 包中找得到.首先挂载一下光盘,查看Packages中 ...

  7. 用 JavaScript 实现简单拼图游戏

    本篇主要讲解,如何利用原生的 JavaScript 来实现一个简单的拼图小游戏. 线上体验地址:拼图 一.游戏的基础逻辑 想用一门语言来开发游戏,必须先了解如何使用这门语言来实现一些基础逻辑,比如图像 ...

  8. webstorm注册码注册

    最近jetbrains公司更新软件总是特别的快,很多私人搭建的server服务也失效了,现出一个能够永久破解的方法,非常简单,只需要2步就完成. 第一步 复制下方activation code,直接粘 ...

  9. windows关于定时执行的php脚本

    根据业务需求,需要服务器每天定时执行一些脚本,如后台提交数据,定时处理数据库等. 最初的思路是在某个控制器里写好方法,加入code验证,定期的用计划任务去访问.由于window计划任务这方面比较low ...

  10. 关于nodejs的线程模型可以看这篇文章

    虽然还是有一些没有讲全,但是整体还是讲的很不错的. http://www.ruanyifeng.com/blog/2014/10/event-loop.html