1 条题解

  • 0
    @ 2025-1-25 17:35:43

    一道大模拟。

    具体解法:首先输入所有的数据,然后根据数据依次模拟即可,使用两重循环,第一重枚举罪犯,第二重枚举星期,如果发现矛盾就退出模拟,未发现矛盾就判断要求的说谎人数是否在可能的说谎人数范围内,在就证明这是一种可能性,否则不是。然后根据可能的罪犯数量输出,00 种可能输出 Impossible11 种可能输出罪犯名字,22 种及以上输出 Cannot Determine

    卡人点:两重循环的时候可能两种模拟都判断出同一个人可能是罪犯,此时不要输出 Cannot Determine

    有一个点有一个人的姓名为 GUILTY,要注意不要改变大小写。

    有一个点有人既说了自己是罪犯,又说自己不是罪犯,这是不可能的,直接输出 Impossible

    有一个点有一个人的姓名为 I,要注意区分 I amI is

    有一个点有一个人说了 I am not guity.,然而 guity 不是 guilty,所以这句话要作废。还有一个点所有人说的都是 guity 不是 guilty,全都要作废,自然要 Cannot Determine。为了加速,可以在 Cannot Determine 时候剪枝一下。

    有一个点人名长达 200200 多个字符,如果使用数组存储字符串记得开大一点。

    本题评测环境为 Linux,但本题测试数据为 Windows 下生成,所以行末可能有个 \r!!这个卡了我很久!!

    好了,上代码:

    #include<bits/stdc++.h>
    using namespace std;
    struct word{
    	string name;
    	int saying;
    	string gname="n";
    };
    string temname;
    string said;
    int m,n,k;
    string name[25];word words[105];
    map<string,int>mp;
    string realguil="Impossible";
    int judge(string saying){
    	temname="n";
    	if(saying=="Today is Monday.")return 1;
    		if(saying=="Today is Tuesday.")return 2;
    		if(saying=="Today is Wednesday.")return 3;
    		if(saying=="Today is Thursday.")return 4;
    		if(saying=="Today is Friday.")return 5;
    		if(saying=="Today is Saturday.")return 6;
    		if(saying=="Today is Sunday.")return 7;
    		if(saying=="I am guilty.")return 1001;
    		if(saying=="I am not guilty.")return 1000;
    		if(saying.size()>11&&saying.substr(saying.size()-10,10)=="is guilty."){
    			temname=saying.substr(0,saying.size()-11);
    			return 2001;
    		}
    		if(saying.size()>15&&saying.substr(saying.size()-14,14)=="is not guilty."){
    			temname=saying.substr(0,saying.size()-15);
    			return 2000;
    		}
    		return 0;
    }
    void init(){
    	for(int i=1;i<=m;i++){
    		mp[name[i]]=-1;
    	}
    }
    bool play(string guil,int week){
    	init();
    	int negs=0,sum=0;
    	for(int i=1;i<=k;i++){
    		if(!words[i].saying)continue;
    		if(words[i].saying<1000){
    			if(words[i].saying!=week){
    				if(mp[words[i].name]==0)return 0;
    				mp[words[i].name]=1;
    			}
    			else{
    				if(mp[words[i].name]==1)return 0;
    				mp[words[i].name]=0;
    			}
    		}
    		else if(words[i].saying<2000){
    			if(words[i].saying==1001){
    				if(words[i].name==guil){
    					if(mp[words[i].name]==1)return 0;
    					mp[words[i].name]=0;
    				}
    				else{
    					if(mp[words[i].name]==0)return 0;
    					mp[words[i].name]=1;
    				}
    			}
    			else{
    				if(words[i].name!=guil){
    					if(mp[words[i].name]==1)return 0;
    					mp[words[i].name]=0;
    				}
    				else{
    					if(mp[words[i].name]==0)return 0;
    					mp[words[i].name]=1;
    				}
    			}
    		}
    		else{
    			if(words[i].saying==2001){
    				if(words[i].gname==guil){
    					if(mp[words[i].name]==1)return 0;
    					mp[words[i].name]=0;
    				}
    				else{
    					if(mp[words[i].name]==0)return 0;
    					mp[words[i].name]=1;
    				}
    			}
    			else{
    				if(words[i].gname!=guil){
    					if(mp[words[i].name]==1)return 0;
    					mp[words[i].name]=0;
    				}
    				else{
    					if(mp[words[i].name]==0)return 0;
    					mp[words[i].name]=1;
    				}
    			}
    		}
    	}
    	for(int i=1;i<=m;i++){
    		if(mp[name[i]]==-1)negs++;
    		else sum+=mp[name[i]];
    	}
    	if(n>=sum&&n<=sum+negs)return 1;
    	return 0;
    }
    int main(){
    	cin>>m>>n>>k;
    	for(int i=1;i<=m;i++){
    		cin>>name[i];
    	}
    	for(int i=1;i<=k;i++){
    		string st;
    		char sp;
    		cin>>st;
    		words[i].name=st.substr(0,st.size()-1); //去掉冒号
    		sp=getchar();
    		getline(cin,st);
    		if(st[st.size()-1]<=32)st=st.substr(0,st.size()-1); //判断句末是否为空格或控制字符,本题中主要用于判断'\r'
    		words[i].saying=judge(st);
    		words[i].gname=temname;
    	}
    	for(int i=1;i<=m;i++){
    		for(int j=1;j<=7;j++){
    			if(play(name[i],j)){
    				if(realguil!="Impossible"){
    					cout<<"Cannot Determine";
    					return 0;
    				}
    				realguil=name[i];
    				break;
    			}
    		}
    	}
    	cout<<realguil;
    	return 0;
    }
    
    
    • 1

    信息

    ID
    5097
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    递交数
    11
    已通过
    4
    上传者