洛谷 P1039 侦探推理

题目:https://www.luogu.org/problemnew/show/P1039

分析:

这道题是一道有技术含量的模拟,我们主要是不要让计算机向人一样思考,只需要让他穷举变化的星期几和当罪犯的人的编号即可,然后就是用string来操作会显得十分方便

#include<iostream> 
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
int n,m,p,fake[21],err,w[200],nx;
string name[100],say[200];
string day[10]={"QAQ","Today is Sunday.","Today is Monday.","Today is Tuesday.","Today is Wednesday.","Today is Thursday.","Today is Friday.","Today is Saturday."};
void set(int who,int yx)
{
    if(fake[who]&&fake[who]!=yx)err=1;
    else fake[who]=yx;
}
int main()
{
    scanf("%d%d%d",&m,&n,&p);
    for(int i=1;i<=m;i++)
        cin>>name[i];
    for(int i=1;i<=p;i++)
	{
        string nm;
        cin>>nm;
        nm.erase(nm.end()-1);
        for(int j=1;j<=m;j++)
        	if(name[j]==nm)
				w[i]=j;

        getline(cin,say[i]);
        say[i].erase(say[i].begin()); 
        say[i].erase(say[i].end()-1);
    }
    for(int td=1;td<=7;td++) 
    for(int px=1;px<=m;px++)
	{
        err=0;
        memset(fake,0,sizeof(fake)); 
        for(int i=1;i<=p;i++)
		{
            int who=w[i];
            if(say[i]=="I am guilty.")set(who,px==who?1:-1);
            if(say[i]=="I am not guilty.")set(who,px!=who?1:-1);
            for(int j=1;j<=7;j++)
            if(say[i]==day[j])set(who,j==td?1:-1);
            for(int j=1;j<=m;j++)
			{
                if(say[i]==name[j]+" is guilty.")set(who,j==px?1:-1);
                if(say[i]==name[j]+" is not guilty.")set(who,j!=px?1:-1);
            }
        }
        int cnt=0,ppp=0;
        for(int i=1;i<=m;i++)
		{
            if(fake[i]==-1)cnt++;
            if(fake[i]==0)ppp++;
        }
        if(!err&&cnt<=n&&cnt+ppp>=n)
            if(nx&&nx!=px)
			{
                printf("Cannot Determine");
                return 0;
            }
			else nx=px;
    }
    if(!nx)printf("Impossible");
    else cout<<name[nx];
    return 0;
}

完结撒花~

posted @ 2018-10-23 20:46  ShineEternal  阅读(91)  评论(0编辑  收藏  举报