模拟题
但是可以用STL快速判断一些东西。
可以枚举罪犯是谁,今天是周几,然后每次判断每个人的话是真的假的,然后判一下假的和不确定的加起来是不是可行。
比较坑的就是关于回车空格什么的要多注意。。。。
#include <iostream> #include <cstdio> #include <string> #include <cstring> using namespace std; const string day[]={"3232","Today is Sunday.","Today is Monday.","Today is Tuesday.","Today is Wednesday.","Today is Thursday.","Today is Friday.","Today is Saturday."},is="I am guilty.",no="I am not guilty."; string name[25],sent[105],tp; int n,m,p,id[105],lie[105],flag; inline void change(int ren,int tag) { tag=tag==0?-1:1; if(lie[ren]&&tag!=lie[ren]) {flag=1;return;} lie[ren]=tag; } 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++) { cin>>tp; tp.erase(tp.end()-1); for(int j=1;j<=m;j++) if(name[j]==tp) id[i]=j; getline(cin,sent[i]); sent[i].erase(sent[i].begin()); if(*(sent[i].end()-1)!='.') sent[i].erase(sent[i].end()-1); } if(*(sent[p].end()-1)!='.') sent[p].erase(sent[p].end()-1); int zf=0; for(int today=1;today<=7;today++) { for(int crim=1;crim<=m;crim++) { flag=0,memset(lie,0,sizeof lie); for(int i=1;i<=p;i++) { if(sent[i]==is) change(id[i],id[i]==crim); if(sent[i]==no) change(id[i],id[i]!=crim); for(int d=1;d<=7;d++) {if(sent[i]==day[d]) change(id[i],d==today);} for(int ren=1;ren<=m;ren++) { if(sent[i]==name[ren]+" is guilty.") change(id[i],ren==crim); if(sent[i]==name[ren]+" is not guilty.") change(id[i],ren!=crim); } } int lier=0,un=0; for(int i=1;i<=m;i++) { if(lie[i]==-1) lier++; if(!lie[i]) un++; } //cout<<lier<<' '<<un<<' '<<flag<<endl; if(!flag&&lier<=n&&lier+un>=n) { if(zf&&zf!=crim) { puts("Cannot Determine"); return 0; } else zf=crim; } } } if(!zf) puts("Impossible"); else cout<<name[zf]; return 0; }