[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题,因为要求 ...
随机推荐
- nginx学习地址
http://www.cnblogs.com/magicsoar/p/5817734.html
- luoguP2742 【模板】二维凸包 / [USACO5.1]圈奶牛 二维凸包
我们知道,纵坐标最小的点一定在凸包上(如果有多个,那它们都会被取到) 随便找一个纵坐标最小的点,将其他所有点按照这个点为原点极角排序,我们发现极角大的会在极角小的后面加入(感性认知一下) 考虑新(加入 ...
- jq——html,text,val和对象访问
html代码 1.html():获取的是对象内的html代码,类似于innerHTML 2.html(代码):设置html的内容,替换 $("div").html("hh ...
- easyUI datagrid的合并的js封装
$.extend($.fn.datagrid.methods, { autoMergeCells : function (jq, fields) { return jq.each(function ( ...
- IOS - 网络指示器
#pragma mark Activity methods - (void)openActivity { // 添加网络指示器 activityIV = [[UIActivityIndicatorVi ...
- UVALive-8078 Bracket Sequence 简单dp
题目链接:https://cn.vjudge.net/problem/UVALive-8078 题意 括号序列T是这样定义的: T是个空的 T是(T), {T}, 或者 [T] T是两个T组成的,比如 ...
- 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 ...
- php获取时间是星期几
PHP星期几获取代码: date("l"); //data就可以获取英文的星期比如Sundaydate("w"); //这个可以获取数字星期比如123,注意0是 ...
- Tarjan缩点【模板】
#include <algorithm> #include <cstdio> #include <map> using namespace std; ); map& ...
- 极路由设置共享磁盘密码、跨网访问samba服务
极路由插上移动硬盘后会自动建立samba服务器,但我们没法去配置哪些盘符需要密码,这样只要在同一个wifi下的电脑都能去访问这些东西了,比较弱智.另外我还想再公司中去读写这个移动硬盘. 设置密码 首先 ...