题目:洛谷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. nginx学习地址

    http://www.cnblogs.com/magicsoar/p/5817734.html

  2. luoguP2742 【模板】二维凸包 / [USACO5.1]圈奶牛 二维凸包

    我们知道,纵坐标最小的点一定在凸包上(如果有多个,那它们都会被取到) 随便找一个纵坐标最小的点,将其他所有点按照这个点为原点极角排序,我们发现极角大的会在极角小的后面加入(感性认知一下) 考虑新(加入 ...

  3. jq——html,text,val和对象访问

    html代码 1.html():获取的是对象内的html代码,类似于innerHTML 2.html(代码):设置html的内容,替换 $("div").html("hh ...

  4. easyUI datagrid的合并的js封装

    $.extend($.fn.datagrid.methods, { autoMergeCells : function (jq, fields) { return jq.each(function ( ...

  5. IOS - 网络指示器

    #pragma mark Activity methods - (void)openActivity { // 添加网络指示器 activityIV = [[UIActivityIndicatorVi ...

  6. UVALive-8078 Bracket Sequence 简单dp

    题目链接:https://cn.vjudge.net/problem/UVALive-8078 题意 括号序列T是这样定义的: T是个空的 T是(T), {T}, 或者 [T] T是两个T组成的,比如 ...

  7. UVA10082-WERTYU(紫书例题3.2)

    A common typing error is to place the hands on the keyboard one row to the right of the correct posi ...

  8. php获取时间是星期几

    PHP星期几获取代码: date("l"); //data就可以获取英文的星期比如Sundaydate("w"); //这个可以获取数字星期比如123,注意0是 ...

  9. Tarjan缩点【模板】

    #include <algorithm> #include <cstdio> #include <map> using namespace std; ); map& ...

  10. 极路由设置共享磁盘密码、跨网访问samba服务

    极路由插上移动硬盘后会自动建立samba服务器,但我们没法去配置哪些盘符需要密码,这样只要在同一个wifi下的电脑都能去访问这些东西了,比较弱智.另外我还想再公司中去读写这个移动硬盘. 设置密码 首先 ...