• [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=='
    '||ch=='
    '||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;
    }
    
  • 相关阅读:
    闰年测试
    EditBox的测试用例设计
    测试工程中的评审
    测试框架
    github
    第一次上机实验
    对软件测试的初步认识
    白盒测试
    Date : 日期对象
    C++ 格式化输出 及 输入 流
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7373794.html
Copyright © 2020-2023  润新知