- 题解
模拟题单L-侦探推理 【题解】
- @ 2026-9-14 15:00:03
题单链接:https://fjnuacm.top/d/minor/contest/668a5cbd8077b67dc5c90da4
由于拒绝承认去年的 行史山是我的代码,因此重写了一下这道题(:
侦探推理-题解:
此题为模拟,主要考验码力,思路其实较为容易想到
记录每个人的指控目标、担保目标,以及认为今天是星期几
随后枚举每个人作为罪犯以及今天的星期,依次枚举,最多枚举 7M 次
对于每次枚举,检查每个人的证词,记录一定说谎的人数 ,以及没有提供任何有效信息的人数
没有提供任何有效信息的人,无法准确判断是否说谎,因此可以自由决定他是否说谎
因此,如果 ,说明这个枚举是可行的,即当前枚举的人可以作为罪犯。
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int m,n,p;
cin>>m>>n>>p;
vector<string> week=
{
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
map<string,int> to;
vector<vector<int>> today;
vector<vector<int>> is;
vector<vector<int>> isnot;
string s;
for(int i=0;i<m;i++)
{
cin>>s;
to[s]=today.size();
today.push_back({});
is.push_back({});
isnot.push_back({});
}
while(p--)
{
cin>>s;
s.pop_back();
getchar();
int t=to[s];
getline(cin,s);
if(s.back()=='\r')s.pop_back();
if(s=="I am guilty.")
{
is[t].push_back(t);
continue;
}
if(s=="I am not guilty.")
{
isnot[t].push_back(t);
continue;
}
for(auto &[u,v]:to)
{
if(s==u+" is guilty.")
{
is[t].push_back(v);
break;
}
if(s==u+" is not guilty.")
{
isnot[t].push_back(v);
break;
}
}
for(int i=0;i<7;i++)
{
if(s=="Today is "+week[i]+".")
{
today[t].push_back(i);
break;
}
}
}
string res;
for(auto &[u,t]:to)
{
for(int j=0;j<7;j++)
{
int unreal=0;
int any=0;
for(int p=0;p<m;p++)
{
int a=0;
int b=0;
for(int i:is[p])
{
if(i==t)a++;
else b++;
}
for(int i:isnot[p])
{
if(i!=t)a++;
else b++;
}
for(int i:today[p])
{
if(i==j) a++;
else b++;
}
if(a&&b)
{
unreal=1e9;
break;
}
if(b)unreal++;
if(a==b)
{
any++;
}
}
if(unreal<=n&&unreal+any>=n)
{
if(res.empty())res=u;
else if(res!=u)
{
cout<<"Cannot Determine";
return 0;
}
break;
}
}
}
if(res.empty())cout<<"Impossible";
else cout<<res;
}
0 条评论
目前还没有评论...