/* 一个神奇的数据 2 2 4 HELLO GUILTY HELLO: What is your name? GUILTY: I am GUILTY. GUILTY: Are you guilty? HELLO: I am not guilty. 答案是“HELLO”,但如果不对大小写敏感则只有一句有效的证词 不说话的人可以当作说真/假话的*/#include <cstdio>#include <cstring>#include <iostream>usingnamespacestd;intm,n,p,nx,fake[22],w[233];//nx记录上一个罪犯(可能没有)的编号,fake[i]记录第i个人有没有说谎(无法判断就是0),w[i]记录第i句话是谁说的stringsaid[233],name[22],day[8]={"hhhh","Today is Sunday.","Today is Monday.","Today is Tuesday.","Today is Wednesday.","Today is Thursday.","Today is Friday.","Today is Saturday."};boolerr;voidadd(intwho,intcur)//1:真话-1:假话0:不知道{if(fake[who]&&fake[who]!=cur)err=1;elsefake[who]=cur;}intmain(){cin>>m>>n>>p;for(inti=1;i<=m;i++)cin>>name[i];for(inti=1;i<=p;i++){stringnm;cin>>nm;nm.erase(nm.end()-1);//去掉:for(intj=1;j<=m;j++)if(name[j]==nm){w[i]=j;//记录第i句话是谁说的break;}getline(cin,said[i]);//记录话的内容said[i].erase(said[i].begin());//去掉空格said[i].erase(said[i].end()-1);//就是这儿awa//把换行符去掉,如果去掉awa,自己电脑能过,不去掉评测能过。//(这是来自luogu题解的神奇操作,但是当时作者好像写反了,现在这个是对的)}for(inttd=1;td<8;td++)//枚举星期{for(intzf=1;zf<=m;zf++)//枚举罪犯{err=0;memset(fake,0,sizeof(fake));//preworkfor(inti=1;i<=p;i++){intwho=w[i];//判断语句情况,可以直接得出人是否说谎if(said[i]=="I am guilty.")add(who,who==zf?1:-1);if(said[i]=="I am not guilty.")add(who,who!=zf?1:-1);for(intj=1;j<=7;j++)if(said[i]==day[j])add(who,j==td?1:-1);for(intj=1;j<=m;j++){if(said[i]==name[j]+" is guilty.")add(who,j==zf?1:-1);if(said[i]==name[j]+" is not guilty.")add(who,j!=zf?1:-1);}}intcnt=0,num=0;//cnt记录说谎人数,num记录不确定的人数(可以看作说真/假话)for(inti=1;i<=m;i++){if(fake[i]==-1)cnt++;if(!fake[i])num++;}if(!err&&cnt<=n&&cnt+num>=n)//情况成立&&说谎人数满足题意{if(nx&&zf!=nx)//之前有过成立的情况{printf("Cannot Determine");return0;}elsenx=zf;//记录成立情况}}}if(!nx)printf("Impossible");//没找到罪犯elsecout<<name[nx];return0;}
共 1 条回复
%%%