专栏文章

题解:P1039 [NOIP 2003 提高组] 侦探推理

P1039题解参与者 6已保存评论 5

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
5 条
当前快照
1 份
快照标识符
@miphs8qz
此快照首次捕获于
2025/12/03 12:13
3 个月前
此快照最后确认于
2025/12/03 12:13
3 个月前
查看原文
很像小学学某思的奥数题。
但是我们的计算机可没有所谓机灵的脑袋,那就枚举所有情景。
模拟每个人是罪犯和今天的日期,模拟每一句话,发现始终说谎的人数。
如果有人真假话都说或者大于 NN 个直接跳过该情景。
如果发现和前面情景推定的凶手不同或者有多个凶手可能性即输出 Cannot Determine
如果所有情景都没有凶手即输出 Impossible
否则即输出名字。
这边输入与判断建议用 string,容易发现 string 比较好比较,插入也很方便。
假设该字符串为 yy,删除最后一个字符用 y.erase(y.length()-1,1);

Code

CPP
#include<bits/stdc++.h>
using namespace std;
int num[25],rub[105];
int n,m,p,wer=0,tf[21];
string name[21];
string bish[105],ans[21];
void dat(int x,int y)
{
	int i,j,t=0,f=0;
	for(i=0;i<p;i++)
	{
		int flag;
		if(bish[i]=="Today is Monday.")
		{
			if(y==1)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="Today is Tuesday.")
		{
			if(y==2)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="Today is Wednesday.")
		{
			if(y==3)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="Today is Thursday.")
		{
			if(y==4)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="Today is Friday.")
		{
			if(y==5)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="Today is Saturday.")
		{
			if(y==6)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="Today is Sunday.")
		{
			if(y==7)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="I am guilty.")
		{
			if(rub[i]==x)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		if(bish[i]=="I am not guilty.")
		{
			if(rub[i]!=x)flag=1;
			else flag=0;
			if(tf[rub[i]]==-1)tf[rub[i]]=flag;
			if(tf[rub[i]]!=flag)return;
		}
		for(j=0;j<m;j++)
		{
			string d=name[j]+" is guilty.";
			if(d==bish[i])
			{
				if(j==x)flag=1;
				else flag=0;
				if(tf[rub[i]]==-1)tf[rub[i]]=flag;
				if(tf[rub[i]]!=flag)return;
			}
		}
		for(j=0;j<m;j++)
		{
			string d=name[j]+" is not guilty.";
			if(d==bish[i])
			{
				if(j!=x)flag=1;
				else flag=0;
				if(tf[rub[i]]==-1)tf[rub[i]]=flag;
				if(tf[rub[i]]!=flag)return;
			}
		}
	}
	for(i=0;i<m;i++)
	{
		if(tf[i]==1)t++;
		if(tf[i]==0)f++;
	}
	if(f>n||t>m-n)return;
	ans[wer++]=name[x];
}
int main()
{
	int i,j;
	scanf("%d%d%d",&m,&n,&p);
	for(i=0;i<m;i++)
		cin>>name[i];
	for(i=0;i<p;i++)
	{
		string x,y;
		cin>>x;
		x.erase(x.length()-1,1);
		for(j=0;j<m;j++)
			if(name[j]==x)rub[i]=j;
		getline(cin,y);
		y.erase(0,1);
		if(y[y.length()-1]=='\n'||y[y.length()-1]=='\r')
			y.erase(y.length()-1,1);
		bish[i]=y;
	}
	for(i=0;i<m;i++)
	{
		for(j=1;j<=7;j++)
		{
			memset(tf,-1,sizeof(tf));
			dat(i,j);
		}
	}
	if(wer<1)
	{
		printf("Impossible");
		return 0;
	}
	string lan=ans[0];
	for(i=1;i<wer;i++)
	{
		if(ans[i]!=lan)
		{
			printf("Cannot Determine");
			return 0;
		}
	}
	cout<<lan;
	return 0;
}
如果你想要珍惜自己的生命这边建议直接跳过该题。

评论

5 条评论,欢迎与作者交流。

正在加载评论...