G-FZU2022- 犯罪嫌疑人

<span style="font-size:24px;">题目链接:<a target=_blank href="http://acm.fzu.edu.cn/problem.php?pid=2202" target="_blank">FZU2022</a></span>
这道题题意很清楚,是推理题,主要靠思维,代码部分比较简单。


<span style="font-size:18px;">以下是解题思路(按照代码顺序编写,可以对照着看):</span>


a[i]表示第i个人被指控的次数,a[i]表示地i个人被澄清的次数,suspect[i]表示第i个人是否为嫌疑人,tmp[]记录那个人的口供。
现在假设第i个人是罪犯,则xx = a[i] + Σb[] - b[i]为所真话的人数。(此处为关键,想到这儿,问题就迎刃而解)
对所有的人 if (xx == m)(m为实际说真话的人数),则第i个人就是嫌疑人,suspect[i]置为1 ,num记录嫌疑人人数。
显然当num == 1时,唯一的嫌疑人就是罪犯,那么谁谁说的是否是真话就显而易见了。
当num != 1时,再看第i个人的供词,如果他指控某个人而这个人是嫌疑人,则他说的话无法判定,反之则说的是假话;如果他为某人澄清,而此人是嫌疑人则他说的话无法判断,反之他说的是真话。
</pre><pre name="code" class="cpp">#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<math.h>
using namespace std;
int a[100005], b[100005], tmp[100005], suspect[100005];
int main(){
	int t;
	scanf("%d", &t);
	while (t--){
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		memset(tmp, 0, sizeof(tmp));
		memset(suspect, 0, sizeof(suspect));
		int m, n;
		int s = 0;
		scanf("%d %d", &n, &m);
		for (int i = 1; i <= n; i++){
			scanf("%d", &tmp[i]);
			if (tmp[i] > 0)
				a[tmp[i]]++;
			else{
				b[-tmp[i]]++;
				s++;
			}
		}
		int num = 0;
		for (int i = 1; i <= n; i++){
			int xx = a[i] + s - b[i];
			if (m == xx){
				suspect[i] = 1;
				num++;
			}
		}
		if (num == 1)
			for (int i = 1; i <= n; i++){
				if (tmp[i] > 0){
					if (suspect[tmp[i]]) printf("Truth\n");
					else printf("Lie\n");
				}
				else{
					if (suspect[-tmp[i]]) printf("Lie\n");
					else printf("Truth\n");
				}
			}
		else{
			for (int i = 1; i <= n; i++){
				if (tmp[i] > 0){
					if (suspect[tmp[i]])printf("Not defined\n");
					else printf("Lie\n");
				}
				else{
					if (suspect[-tmp[i]])printf("Not defined\n");
					else printf("Truth\n");
				}
			}
		}

	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值