題目描述
明明同學最近迷上了偵探漫畫《柯南》並沉醉於推理遊戲之中,於是他召集了一羣同學玩推理遊戲。遊戲的內容是這樣的,明明的同學們先商量好由其中的一個人充當罪犯(在明明不知情的情況下),明明的任務就是找出這個罪犯。接着,明明逐個詢問每一個同學,被詢問者可能會說:
證詞中出現的其他話,都不列入邏輯推理的內容。
明明所知道的是,他的同學中有N個人始終說假話,其餘的人始終說真。
現在,明明需要你幫助他從他同學的話中推斷出誰是真正的兇手,請記住,兇手只有一個!
輸入
輸入由若干行組成,第一行有二個整數,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100);
M是參加遊戲的明明的同學數,N是其中始終說謊的人數,P是證言的總數。接下來M行,
每行是明明的一個同學的名字(英文字母組成,沒有主格,全部大寫)。
往後有P行,每行開始是某個同學的名宇,緊跟着一個冒號和一個空格,後面是一句證詞,符合前表中所列格式。證詞每行不會超過250個字符。
輸入中不會出現連續的兩個空格,而且每行開頭和結尾也沒有空格。
輸出
如果你的程序能確定誰是罪犯,則輸出他的名字;如果程序判斷出不止一個人可能是
罪犯,則輸出 Cannot Determine;如果程序判斷出沒有人可能成爲罪犯,則輸出 Impossible。
樣例輸入
2 2 4HELLOGUILTYHELLO: What is your name?GUILTY: I am GUILTY.GUILTY: Are you guilty?HELLO: I am not guilty.
樣例輸出
HELLO
思路就是枚舉星期幾那麼就可以推理出來了,其他的...自己看吧,去年寫的...
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
map<string,int>Map;
int num[105],f[21],m,n,i,j,k,p,flag,now,lie,len,cnt,today,t;
char a[21][205],name[105][205],s[105][21][205],ans[101][205];
char day[8][25]={" ","Monday.","Tuesday.","Wednesday.","Thursday.","Friday.","Saturday.","Sunday."};
bool cmp(char *a,char *b)
{
int l1=strlen(a),l2=strlen(b);
if(l1!=l2)return false;
for(int i=0;i<l1;i++)if(a[i]!=b[i])return false;
return true;
}
int check1(int k)
{
if(!cmp(s[k][num[k]],"guilty.")||(num[k]!=3&&num[k]!=4))return 2;
if(s[k][1][0]!='I'||s[k][1][1]!='\0'||!cmp(s[k][2],"am"))return 2;
if(num[k]==4&&!cmp(s[k][3],"not"))return 2;
if(Map[name[k]]==now)return num[k]!=3;
return num[k]==3;
}
int check2(int k)
{
if(!cmp(s[k][num[k]],"guilty.")||(num[k]!=3&&num[k]!=4||!cmp(s[k][2],"is")))return 2;
if(num[k]==4&&!cmp(s[k][3],"not"))return 2;
if(Map[s[k][1]]==now)return num[k]!=3;
return num[k]==3;
}
int check3(int k)
{
if(num[k]!=3||!cmp(s[k][1],"Today")||!cmp(s[k][2],"is"))return 2;
return !cmp(day[today],s[k][3]);
}
int work()
{
now=Map[a[p]];
int r=0,another=0;
memset(f,0,sizeof(f));
for(int i=1;i<=m;i++)
{
int t1=check1(i),t2=check2(i),t3=check3(i),pre=Map[name[i]];
if(!t1||!t2||!t3)
{
if(f[pre]==2)return 0;
f[pre]=1;
}
if(t1&1||t2&1||t3&1)
{
if(f[pre]==1)return 0;
f[pre]=2;
}
}
for(int i=1;i<=n;i++)
{
if(f[i]==2)r++;
else if(!f[i])another++;
}
return (r<=lie&&r+another>=lie);
}
int main()
{
cin>>n>>lie>>m;
for(i=1;i<=n;i++)
{
cin>>a[i];
Map[a[i]]=i;
}
for(i=1;i<=m;i++)
{
cin>>name[i];
name[i][strlen(name[i])-1]='\0';
num[i]=1;
cin>>s[i][num[i]];
while(isalpha((s[i][num[i]][strlen(s[i][num[i]])-1])))cin>>s[i][++num[i]];
}
for(p=1;p<=n;p++)
{
flag=0;
for(today=1;today<=7&&!flag;today++)flag=work();
if(flag)memcpy(ans[++cnt],a[p],sizeof(a[p]));
}
if(!cnt)cout<<"Impossible";
else if(cnt==1)cout<<ans[cnt];
else cout<<"Cannot Determine";
return 0;
}