1. 程式人生 > >LUOGU P1039 偵探推理 (字串+模擬)

LUOGU P1039 偵探推理 (字串+模擬)

傳送門

解題思路

  一道%你神題,\(string\)好強大啊。。首先列舉一個周幾,再列舉一個罪犯是誰,然後判斷的時候就是列舉所有人說的話。定義\(fAKe[i]\)表示第\(i\)個人說的是真話還是假話還是未知。然後如果遇到\(xx is guilty\)\(I am guilty\)之類的話,就看列舉的罪犯是否為這個人。如果說的是\(Today is xxx\),就看當前列舉的星期是否為這一天。

程式碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<string>
#include<map>

using namespace std;
const int MAXN = 25;

int n,m,p,fAKe[MAXN],w[205],ans,now,err;
string name[MAXN],say[205];
string day[10]={"","Today is Sunday.","Today is Monday.","Today is Tuesday.","Today is Wednesday."
                ,"Today is Thursday.","Today is Friday.","Today is Saturday."};
map<string,int> mp;

void solve(int x,int y){
    if(!fAKe[x]) fAKe[x]=y;
    else if(fAKe[x] && fAKe[x]!=y) err=1;
}

int main(){
    scanf("%d%d%d",&m,&n,&p);
    for(int i=1;i<=m;i++) cin>>name[i],mp[name[i]]=i;
    for(int i=1;i<=p;i++){
        string nm;cin>>nm;
        nm.erase(nm.end()-1);w[i]=mp[nm];
        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 chp=1;chp<=m;chp++){ //列舉罪犯 
            err=0;int who,cnt,pp;
            memset(fAKe,0,sizeof(fAKe));
            for(int i=1;i<=p;i++){
                who=w[i];
                if(say[i]=="I am guilty.") solve(who,who==chp?1:-1); 
                if(say[i]=="I am not guilty.") solve(who,who==chp?-1:1);
                for(int j=1;j<=7;j++) 
                    if(say[i]==day[j]) {solve(who,j==td?1:-1);break;}
                for(int j=1;j<=m;j++){
                    if(say[i]==name[j]+" is guilty.") solve(who,chp==j?1:-1);
                    if(say[i]==name[j]+" is not guilty.") solve(who,chp==j?-1:1);
                }       
            }
            cnt=pp=0;
            for(int i=1;i<=m;i++) {
                if(!fAKe[i]) pp++;
                if(fAKe[i]==-1) cnt++;
            }
            if(err || cnt>n || cnt+pp<n) continue;        
            if(ans && ans!=chp) {
                puts("Cannot Determine");
                return 0;
            }
            ans=chp;
        }
    if(ans) cout<<name[ans];
    else puts("Impossible");
    return 0;
}