luogu P1039 侦探推理

#include <bits/stdc++.h>
using namespace std;
int n,m,p,cnt,today,is_guilty[110],may[110];
map<string,int> mp,week;
map<int,string> guilty;
struct zhengci{int id; string s,who;}z[110];
bool vis[110],flag;

void check(){
	memset(is_guilty,-1,sizeof(is_guilty));
	today=0;
	for(int i=1;i<=cnt;i++){
		int u=mp[z[i].who],id=z[i].id; string v=z[i].s;
		if(!vis[u]){
			if(id==1){
				if(is_guilty[mp[v]]==0)return;
				is_guilty[mp[v]]=1;
			}
			else if(id==2){
				if(is_guilty[mp[v]]==1)return;
				is_guilty[mp[v]]=0;
			}
			else {
				if(!today)today=week[v];
				else if(today!=week[v])return;
			}
		}
		else {
			if(id==2){
				if(is_guilty[mp[v]]==0)return;
				is_guilty[mp[v]]=1;
			}
			else if(id==1){
				if(is_guilty[mp[v]]==1)return;
				is_guilty[mp[v]]=0;
			}
			else {
				if(!today)continue;
				else if(today==week[v])return;
			}
		}
	}
	int sum=0,maybe;
	for(int i=1;i<=n;i++)if(is_guilty[i]==1)sum++,maybe=i;
	if(sum>1)flag=1;
	if(sum==1)may[maybe]=1;
	else if(sum==0){
		for(int i=1;i<=n;i++)if(is_guilty[i]==0)sum++;
		if(sum==n-1)for(int i=1;i<=n;i++)if(is_guilty[i]!=0)may[i]=1;
		if(sum!=n-1)flag=1;
	}
}

void dfs(int now,int sum){
	if(sum==m){check(); return;}
	for(int i=now+1;i<=n;i++){
		vis[i]=1;
		dfs(i,sum+1);
		vis[i]=0;
	}
}

int main(){
	week["Monday"]=1; week["Tuesday"]=2; week["Wednesday"]=3; week["Thursday"]=4; week["Friday"]=5; week["Saturday"]=6; week["Sunday"]=7;
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=n;i++){
		string s;
		cin>>s;
		guilty[i]=s;
		s+=':';
		mp[s]=i;
	}
	for(int i=1;i<=p;i++){
		string name,zc;
		cin>>name;
		getchar();
		getline(cin,zc);
		zc.erase(zc.end()-1);
		if(zc=="I am guilty."){z[++cnt].id=1;z[cnt].s=name;z[cnt].who=name;}
		else if(zc=="I am not guilty."){z[++cnt].id=2;z[cnt].s=name;z[cnt].who=name;}
		else {
			int t=0; string s="";
			while(zc[t]!=' ')s+=zc[t++];
			if(mp[s+':']){
				if(zc==s+" is guilty."){z[++cnt].id=1;z[cnt].s=s+':';z[cnt].who=name;}
				else if(zc==s+" is not guilty."){z[++cnt].id=2;z[cnt].s=s+':';z[cnt].who=name;}
			}
			else if(s=="Today"){
				s+=' '; t++;
				while(zc[t]!=' ')s+=zc[t++];
				if(s=="Today is"){
					string ss=""; t++;
					while(zc[t]!='.')ss+=zc[t++];
					if(week[ss]){z[++cnt].id=3;z[cnt].s=ss;z[cnt].who=name;}
				}
			}
		}
	}
	//for(int i=1;i<=cnt;i++)cout<<z[i].id<<':'<<z[i].who<<z[i].s<<endl;
	dfs(0,0);
	int sum=0,maybe;
	for(int i=1;i<=n;i++)if(may[i])sum++,maybe=i;
	if(sum==0 && !flag)puts("Impossible");
	else if(sum==1)cout<<guilty[maybe]<<endl;
	else puts("Cannot Determine");
	return 0;
}


/*
3 1 5
MIKE
CHARLES
KATE
MIKE: I am guilty.
MIKE: I am not guilty.
CHARLES: MIKE is guilty.
CHARLES: MIKE is not guilty.
KATE: Today is Monday.
*/

  

原文地址:https://www.cnblogs.com/codetogether/p/13416358.html