标签:codeforces
题意:
有n个嫌疑犯,现在他们说出情况+a[i]表示说a[i]犯罪了,-a[i]表示说a[i]没有犯罪。其中只有一个是罪犯,并且有且只有m个人说的是真话,问最后谁在说谎,谁在说真话,谁的话又是不确定的。
分析:
刚开始拿到这个题,感觉很难下手,想到如何判定凶手的时候就会觉得很烦,大概是有感情因素在里面吧,不够有条理性。
首先假设有5个人,那么说出的情况可能是-1,+1,-2,+2,-3,+3,-4,+4,-5,+5 那么假设1 是凶手,说真话的人必定是m个。好的,那么这个时候说真话的人是(确定是+1的)+(确定其他是负值)的情况和。如果这个和为m,那么这个人是罪犯,如果罪犯的人数大于一,那么谁不是罪犯依然可以确定,但是如果谁是罪犯那就不确定了。
最后再根据每个人说的和实际情况的对比,如果不一致就是撒谎,一致就是说真话,罪犯大于一的时候罪犯不能确定,其他情况可以确定。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <queue>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define write freopen("output.txt","w",stdout)
#define LL long long
using namespace std;
typedef pair<int, int> pii;
const int inf = 0x7fffffff;
const int maxn = 10005;
const int mod = 1000000007;
int a[maxn],b[maxn],c[maxn],sc[maxn];
int vis[maxn];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int i,j;
memset(sc,0,sizeof(sc));
memset(vis,0,sizeof(vis));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]>0)b[a[i]]++;
else c[-a[i]]++;
}
int cnt=0;
for(i=1;i<=n;i++)sc[i]=sc[i-1]+c[i];
for(i=1;i<=n;i++)
{
if(b[i]+sc[i-1]+sc[n]-sc[i]==m)
{
vis[i]=1;
cnt++;
}
}
for(i=1;i<=n;i++)
{
if(a[i]>0 && (vis[a[i]]==0))puts("Lie");
else if(a[i]<0 && vis[-a[i]]==0)puts("Truth");
else if(a[i]>0 && (vis[a[i]]==1))
{
if(cnt>1)puts("Not defined");
else puts("Truth");
}
else if(a[i]<0 && vis[-a[i]]==1)
{
if(cnt>1)puts("Not defined");
else puts("Lie");
}
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:codeforces
原文地址:http://blog.csdn.net/u010582475/article/details/48085069