1 条题解
-
0
一道大模拟。
具体解法:首先输入所有的数据,然后根据数据依次模拟即可,使用两重循环,第一重枚举罪犯,第二重枚举星期,如果发现矛盾就退出模拟,未发现矛盾就判断要求的说谎人数是否在可能的说谎人数范围内,在就证明这是一种可能性,否则不是。然后根据可能的罪犯数量输出, 种可能输出
Impossible
, 种可能输出罪犯名字, 种及以上输出Cannot Determine
。卡人点:两重循环的时候可能两种模拟都判断出同一个人可能是罪犯,此时不要输出
Cannot Determine
。有一个点有一个人的姓名为
GUILTY
,要注意不要改变大小写。有一个点有人既说了自己是罪犯,又说自己不是罪犯,这是不可能的,直接输出
Impossible
。有一个点有一个人的姓名为
I
,要注意区分I am
和I is
。有一个点有一个人说了
I am not guity.
,然而guity
不是guilty
,所以这句话要作废。还有一个点所有人说的都是guity
不是guilty
,全都要作废,自然要Cannot Determine
。为了加速,可以在Cannot Determine
时候剪枝一下。有一个点人名长达 多个字符,如果使用数组存储字符串记得开大一点。
本题评测环境为 Linux,但本题测试数据为 Windows 下生成,所以行末可能有个
\r
!!这个卡了我很久!!好了,上代码:
#include<bits/stdc++.h> using namespace std; struct word{ string name; int saying; string gname="n"; }; string temname; string said; int m,n,k; string name[25];word words[105]; map<string,int>mp; string realguil="Impossible"; int judge(string saying){ temname="n"; if(saying=="Today is Monday.")return 1; if(saying=="Today is Tuesday.")return 2; if(saying=="Today is Wednesday.")return 3; if(saying=="Today is Thursday.")return 4; if(saying=="Today is Friday.")return 5; if(saying=="Today is Saturday.")return 6; if(saying=="Today is Sunday.")return 7; if(saying=="I am guilty.")return 1001; if(saying=="I am not guilty.")return 1000; if(saying.size()>11&&saying.substr(saying.size()-10,10)=="is guilty."){ temname=saying.substr(0,saying.size()-11); return 2001; } if(saying.size()>15&&saying.substr(saying.size()-14,14)=="is not guilty."){ temname=saying.substr(0,saying.size()-15); return 2000; } return 0; } void init(){ for(int i=1;i<=m;i++){ mp[name[i]]=-1; } } bool play(string guil,int week){ init(); int negs=0,sum=0; for(int i=1;i<=k;i++){ if(!words[i].saying)continue; if(words[i].saying<1000){ if(words[i].saying!=week){ if(mp[words[i].name]==0)return 0; mp[words[i].name]=1; } else{ if(mp[words[i].name]==1)return 0; mp[words[i].name]=0; } } else if(words[i].saying<2000){ if(words[i].saying==1001){ if(words[i].name==guil){ if(mp[words[i].name]==1)return 0; mp[words[i].name]=0; } else{ if(mp[words[i].name]==0)return 0; mp[words[i].name]=1; } } else{ if(words[i].name!=guil){ if(mp[words[i].name]==1)return 0; mp[words[i].name]=0; } else{ if(mp[words[i].name]==0)return 0; mp[words[i].name]=1; } } } else{ if(words[i].saying==2001){ if(words[i].gname==guil){ if(mp[words[i].name]==1)return 0; mp[words[i].name]=0; } else{ if(mp[words[i].name]==0)return 0; mp[words[i].name]=1; } } else{ if(words[i].gname!=guil){ if(mp[words[i].name]==1)return 0; mp[words[i].name]=0; } else{ if(mp[words[i].name]==0)return 0; mp[words[i].name]=1; } } } } for(int i=1;i<=m;i++){ if(mp[name[i]]==-1)negs++; else sum+=mp[name[i]]; } if(n>=sum&&n<=sum+negs)return 1; return 0; } int main(){ cin>>m>>n>>k; for(int i=1;i<=m;i++){ cin>>name[i]; } for(int i=1;i<=k;i++){ string st; char sp; cin>>st; words[i].name=st.substr(0,st.size()-1); //去掉冒号 sp=getchar(); getline(cin,st); if(st[st.size()-1]<=32)st=st.substr(0,st.size()-1); //判断句末是否为空格或控制字符,本题中主要用于判断'\r' words[i].saying=judge(st); words[i].gname=temname; } for(int i=1;i<=m;i++){ for(int j=1;j<=7;j++){ if(play(name[i],j)){ if(realguil!="Impossible"){ cout<<"Cannot Determine"; return 0; } realguil=name[i]; break; } } } cout<<realguil; return 0; }
信息
- ID
- 5097
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 11
- 已通过
- 4
- 上传者