【FZU - 2202】犯罪嫌疑人(思维,假装建图,分类讨论)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/89025949

题干:

福尔摩斯是个大侦探,他总是在解决疑难案件。这一次的案件也不例外,案件是这样的:有编号为1到N的N位嫌疑犯,他们其中有一个犯了罪,然后每个嫌疑犯都被询问,“哪一个人犯了罪?”犯罪嫌疑人的答案只能“编号ai的嫌疑犯犯了罪”或者“编号ai的嫌疑犯没有犯罪”。当然嫌疑犯也可以说他自己(ai = i).

福尔摩斯凭着他敏锐的侦探直觉,确定地对华生说,只有M个人说了真话,其余人都是说谎。然后就没有然后了,但华生却想知道哪些人说谎哪些人又是讲真话。这个时候同样聪明的你,被誉为红旗下的名侦探是否愿意秀一下自己的侦探天赋,帮助可怜的华生嘛?

Input

第一行一个整数T(1 <= T <= 10),表示测试数据的组数。

每组数据第一行包含N(1 <= N <=10^5)和M(0 <= M <= N)两个整数,含义见题面。接下来N行,第i行是一个整数+ai或者-ai(1<= ai <= N),如果是+ai,代表第i个人说编号ai犯了罪,如果是-ai,则表示编号ai没有犯罪。

输入数据保证至少存在一个人,使得如果是他犯了罪,则恰好有 M 个人说了真话。

Output

输出为N行,第i行是第i个嫌疑犯的输出。如果第i个嫌疑犯说了是真话,输出“Truth”;如果说谎,则输出“Lie”,如果不确定,则输出“Not defined”。

Sample Input

2
3 2
-1
-2
-3
4 1
+2
-3
+4
-1

Sample Output

Not defined
Not defined
Not defined
Lie
Not defined
Lie
Not defined

解题报告:

这题本来以为是要建图的,但是其实对于判断m个人不太好处理,wjh大佬灵光一闪就有了思路。

in1数组记录有多少个人觉得他犯罪了,in2数组记录有多少个人觉得他没犯罪。all1变量记录总共有多少人的陈述是“犯罪”,all2变量记录总共有多少人的陈述是“没犯罪”。那么对于第i个人 x= in1[i]+all2-in2[i]  就代表  假设第i个人是犯罪的候选人(因为题目说可,只有一个人犯罪了,但是可能有多个人是“可能犯罪的”,以下称之为 候选人),那么有x个人说了真话。如果x==m,那么这个就是候选人。我们枚举每一个人当犯罪者,看通过这个方法可以筛选出多少个候选人。然后分别处理。

如果只有一个候选人,那么就是说谎或者没说谎就是了。

如果有多个候选人,那么如果某个人说的f[i]那个人不在候选人里面,那这个人肯定要么说谎了要么没说谎。如果这个人说的f[i]那个人在候选人里面,那么就输出不确定。

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#define mod (1000000007)
using namespace std;
typedef long long ll;
int in1[100100];//犯罪
int in2[100100];//说没犯罪
int f[100100];//关系
bool ans[100100];
int main() 
{
	int t;
	scanf("%d",&t);
	while(t--) {
		int all1=0,all2=0; //总-犯 总-不
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=1; i<=n; i++) {
			ans[i]=in1[i]=in2[i]=0;
		}
		for(int v,i = 1; i<=n; i++) {
			scanf("%d",&v);
			f[i]=v;
			if(v>0) all1++,in1[v]++;
			else all2++,in2[-v]++;
		}
		int cnt=0;
		int id;
		for(int i=1; i<=n; i++) {
			int tm=in1[i]+all2-in2[i];
			if(tm==m) {
				id=i;
				cnt++;
				ans[i]=1;
			}
		}
		if(cnt==1) {
			for(int i=1; i<=n; i++) {
				if(abs(f[i])==id) { //ans[0])
					if(f[i]>0) printf("Truth\n");
					else printf("Lie\n");
				} 
				else {
					if(f[i]<0) printf("Truth\n");
					else printf("Lie\n");
				}
			}
		} 
		else {
			for(int i=1; i<=n; i++) {
				if(ans[abs(f[i])]==1) {
					if(f[i]>0)puts("Not defined");
					else puts("Not defined");
				} 
				else {
					if(f[i]<0) puts("Truth");
					else puts("Lie");
				}
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/89025949