CF156B Suspects 【逻辑+】

本文介绍了一种通过分析犯人之间的相互供述来确定真实情况的方法。利用数学逻辑推理,判断哪些供述可能是真实的,哪些可能是谎言。适用于解决特定类型的逻辑谜题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出n个犯人的n条供述,并且知道有m条是真的

正数代表当前犯人供述该号犯人犯罪

负数代表当前犯人供述该号犯人没有犯罪

例如

+7代表当前犯人供述7号犯罪

-3代表当前犯人供述3号没有犯罪

 

来想想某人可能犯罪的条件

假设一个人犯罪

那么如果

说其他人犯罪的供述(暂时视作假话)条数+说他没有犯罪的供述(暂时视作假话)条数=n-m(假话条数)

这个式子成立的话

那么这个人就有可能犯罪(因为可能有多个人满足这个条件,而犯人只有一个)

否则

这个人不可能犯罪

 

那么对可能犯罪的人

如果不止一个

说他犯罪的属于not define

说他没犯罪的属于not define

如果只有一个

说他犯罪的属于true

说他没犯罪的属于lie

 

那么对不可能犯罪的人

说他犯罪的属于lie

说他没犯罪的属于true

 

#include <cstdio>
#include <climits>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int NN=1111111;
int tmp[NN];
int y[NN],nono[NN],maybe[NN];
int main(){
#ifndef ONLINE_JUDGE
	freopen("/home/rainto96/in.txt","r",stdin);
#endif
	int n,m;
	cin>>n>>m;
	int yes=0,no=0;
	for(int i=1;i<=n;i++){
		cin>>tmp[i];
		//vis[abs(tmp)]+=tmp/abs(tmp);
		if(tmp[i]>0) y[tmp[i]]++;
		else 	  nono[-tmp[i]]++;
		yes+=tmp[i]>0;
		no+=tmp[i]<0;
	}
	for(int i=1;i<=n;i++){
		maybe[i]=(yes-y[i]+nono[i]==n-m);
	}
	/*char statement[2][2][111]={{"Not defined","TRUETH"},{"Not defined","LIE"}};
	for(int i=1;i<=n;i++){
		if(tmp[i]>0){
			printf("%s\n",statement[1][!maybe[tmp[i]]]);
		}else{
			printf("%s\n",statement[0][maybe[-tmp[i]]]);
		}
	}*/
	int times=0;
	for(int i=1;i<=n;i++)   if(maybe[i]) times++;
	for(int i=1;i<=n;i++){
		if(tmp[i]>0){
			if(maybe[tmp[i]]){
                                if(times>1) cout<<"Not defined"<<endl;
                                else        cout<<"Truth"<<endl;
			}else         cout<<"Lie"<<endl;
		}else{
			if(maybe[-tmp[i]]){
                                if(times>1) cout<<"Not defined"<<endl;
                                else        cout<<"Lie"<<endl;
			}else         cout<<"Truth"<<endl;
		}
	}
	return 0;
}


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值