$NOIP2003$侦探推理

\(NOIP2003\)侦探推理

不行我没忍住,这道恶心的模拟写出来了,一定要发文祭奠一下

话说我这么清晰的命名方式应该是个人都看得懂吧

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int f=1,w=0;char x=0;
    while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
    while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
    return w*f;
}
const int N=25;
const int P=110;
int n,m,K,Sum;
struct Students
{
	string Name;
	int Hon,Crm,Sum;
	vector<string> Word;
} p[N];
map<string,int> Name_MAP,Day,ANS;
map<string,string> Gul,NGul;
inline void get(string &x)
{
    char c=getchar();
    while(c=='\n'||c=='\r') c=getchar();
    while(c!='\n'&&c!='\r') x+=c,c=getchar();
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("A.in","r",stdin);
#endif
	scanf("%d%d%d",&m,&n,&K);
	for(int i=1;i<=m;i++)
	{
		char X=getchar();while(X=='\n'||X=='\r') X=getchar();
		while(X!='\n'&&X!='\r') p[i].Name+=X,X=getchar();
		Name_MAP[p[i].Name]=i;
	}
	for(int i=1;i<=K;i++)
	{
		string S,NAME;char X=getchar();
		while(X=='\n'||X=='\r') X=getchar();
		while(X!=':') NAME+=X,X=getchar();
		while(X=='\n'||X=='\r'||X==' '||X==':') X=getchar();
		while(X!='\n'&&X!='\r') S+=X,X=getchar();
		p[Name_MAP[NAME]].Word.push_back(S);
	}
	Day["Today is Monday."]=1;Day["Today is Tuesday."]=2;
	Day["Today is Wednesday."]=3;Day["Today is Thursday."]=4;
	Day["Today is Friday."]=5;Day["Today is Saturday."]=6;
	Day["Today is Sunday."]=7;
	for(int i=1;i<=m;i++) Gul[p[i].Name+" is guilty."]=p[i].Name;
	for(int i=1;i<=m;i++) NGul[p[i].Name+" is not guilty."]=p[i].Name;
	for(int Ts=0;Ts<(1<<m);Ts++)
	{
		int Cnt_UNKOWN=0,Cnt_GUL=0,Cnt_NGUL=0,Cnt=0,Today=0;
		for(int i=0;i<m;i++) if(!(Ts&(1<<i))) Cnt++;
		if(Cnt!=n) continue;
		for(int i=0;i<m;i++) p[i+1].Hon=0;
		for(int i=0;i<m;i++) p[i+1].Hon=(bool)(Ts&(1<<i));
		for(int i=1;i<=m;i++) p[i].Crm=-1,p[i].Crm=-1;
		for(int i=1;i<=m;i++)
		{
			if(p[i].Hon)
			{
				for(int j=0;j<(int)p[i].Word.size();j++)
				{
					if(p[i].Word[j]=="I am guilty.")
					{
						if(p[i].Crm==-1||p[i].Crm==1) p[i].Crm=1;
						else goto This_is_False; continue;
					}
					if(p[i].Word[j]=="I am not guilty.")
					{
						if(p[i].Crm==-1||p[i].Crm==0) p[i].Crm=0;
						else goto This_is_False; continue;
					}
					if(Gul[p[i].Word[j]].size())
					{
						if(p[Name_MAP[Gul[p[i].Word[j]]]].Crm==-1)
							p[Name_MAP[Gul[p[i].Word[j]]]].Crm=1;
						else if(p[Name_MAP[Gul[p[i].Word[j]]]].Crm==1)
							p[Name_MAP[Gul[p[i].Word[j]]]].Crm=1;
						else goto This_is_False; continue;
					}
					if(NGul[p[i].Word[j]].size())
					{
						if(p[Name_MAP[NGul[p[i].Word[j]]]].Crm==-1)
							p[Name_MAP[NGul[p[i].Word[j]]]].Crm=0;
						else if(p[Name_MAP[NGul[p[i].Word[j]]]].Crm==0)
							p[Name_MAP[NGul[p[i].Word[j]]]].Crm=0;
						else goto This_is_False; continue;
					}
					if(Day[p[i].Word[j]])
					{
						if(Today==Day[p[i].Word[j]]) Today=Day[p[i].Word[j]];
						else if(Today==0) Today=Day[p[i].Word[j]];
						else goto This_is_False; continue;
					}
				}
			}
			else
			{
				for(int j=0;j<(int)p[i].Word.size();j++)
				{
					if(p[i].Word[j]=="I am guilty.")
					{
						if(p[i].Crm==-1||p[i].Crm==0) p[i].Crm=0;
						else goto This_is_False; continue;
					}
					if(p[i].Word[j]=="I am not guilty.")
					{
						if(p[i].Crm==-1||p[i].Crm==1) p[i].Crm=1;
						else goto This_is_False; continue;
					}
					if(Gul[p[i].Word[j]].size())
					{
						if(p[Name_MAP[Gul[p[i].Word[j]]]].Crm==-1)
							p[Name_MAP[Gul[p[i].Word[j]]]].Crm=0;
						else if(p[Name_MAP[Gul[p[i].Word[j]]]].Crm==0)
							p[Name_MAP[Gul[p[i].Word[j]]]].Crm=0;
						else goto This_is_False; continue;
					}
					if(NGul[p[i].Word[j]].size())
					{
						if(p[Name_MAP[NGul[p[i].Word[j]]]].Crm==-1)
							p[Name_MAP[NGul[p[i].Word[j]]]].Crm=1;
						else if(p[Name_MAP[NGul[p[i].Word[j]]]].Crm==1)
							p[Name_MAP[NGul[p[i].Word[j]]]].Crm=1;
						else goto This_is_False; continue;
					}
					if(Day[p[i].Word[j]])
						if(Today==Day[p[i].Word[j]]&&Today)
							goto This_is_False;
				}
			}
		}
		for(int i=1;i<=m;i++)
			if(p[i].Crm==-1) Cnt_UNKOWN++;
			else if(p[i].Crm==1) Cnt_GUL++;
			else if(p[i].Crm==0) Cnt_NGUL++;
		if(Cnt_GUL>1) goto This_is_False;
		if(Cnt_UNKOWN+Cnt_NGUL==m&&Cnt_UNKOWN>1)
		{
			puts("Cannot Determine");return 0;
		}
		if(Cnt_UNKOWN+Cnt_NGUL==m&&Cnt_UNKOWN==1)
		{
			Cnt_GUL=Cnt_UNKOWN;
			for(int i=1;i<=m;i++)
				if(p[i].Crm==-1) p[i].Crm=1;
		}
		if(Cnt_GUL==1)
			for(int i=1;i<=m;i++)
				if(p[i].Crm==1) p[i].Sum++;
	  This_is_False:;
	}
	for(int i=1;i<=m;i++) if(p[i].Sum) Sum++;
	if(Sum==1)
	{
		for(int i=1;i<=m;i++)
			if(p[i].Sum) cout<<p[i].Name<<endl;
	}
	else if(Sum!=0) puts("Cannot Determine");
	else puts("Impossible");
}
posted @ 2019-11-05 14:53  风骨傲天  阅读(142)  评论(0编辑  收藏  举报