期中考试第10题

题目简介:

在《三体》中的三体文明接触了人类文明以后逐渐开始学会了说假话,于是三体社会中流行起了聚在一起评论别人说的话是真是假的活动。有一天,N个人(编号范围[0,N−1])聚在一起,每个人都说了一句:“a i说的是真/假话”。现在,围观的你想知道他们每个人说的是真还是假?

输入格式
第一行一个整数N,表示有N个人后面接着N行,其中第i行表示编号为i的人说的话,每行有两个整数a
i和bi,表示编号为i的人说编号为a i的人说的是真话(b i=1)或假话(b i=0)
数据范围:1<=N<=15,0<=ai<N,bi∈{0,1}

输出格式
N个整数,第i个整数为1表示编号为 i 的人实际在说真话,为0表示编号为 i 的人实际在说假话。
若有多种情况,则输出字典序最小的一个。
例如:

inputoutput
2 0 0 1 00 1
3 1 1 0 1 0 00 0 1

解释:
第一组数据:一共有2个人,第一个人说0号说的是假(0)话,第二个人说1号说的是假(0)话。
第二组数据:一共有3个人,第一个人说1号说的是真(1)话,第二个人说0号说的是真(1)话,第三个人说0号说的是假(0)话。这个时候有两种情况是对的,即1 1 0 和 0 0 1, 但输出字典序小的 0 0 1

思路:

1.首先假设可能的情况, 暴力从全是假话即全为0开始,遍历到全是真话即全为1。要求按照字典序输出,就可以想到是真值表的增加方式。
2.按照所假设的情况进行推理比较,如果某个人说的话与我所假设的矛盾那么就在真值表加一继续遍历,直到我的假设与他们所说的话没有矛盾。
3.输出最后的真值表即为答案

代码:

#include <iostream>
using namespace std;
int n;
int p[2][15]={0};//k said that what p[0][k] said is p[1][k]
int t[15]={0};//truth table, what k said is t[k]
int add_t(){
	t[n-1]++;
	int carry=0;
	for(int i=n-1;i>=0;i--){
		t[i]+=carry;
		carry=t[i]/2;
		t[i]%=2;
	}
	return carry;//when t[0]--t[n-1] are all 1, return 1;else return 0;
}
int inv(int a){
	if(a) return 0;
	else return 1;
}
int main(){
	cin>>n;
	int i;
	for(i=0;i<n;i++){
		cin>>p[0][i]>>p[1][i];
	}
	do{
		int flag=1;//flag==1 represent that there's no logical conflict
		for(int k=0;k<n;k++){
			if(t[k]&&t[p[0][k]]!=p[1][k]||!t[k]&&t[p[0][k]]==p[1][k]){//there's a logical conflict
				flag=0;break;
			}
		}
		if(flag==1) break;
	}while(inv(add_t()));
	for(i=0;i<n;i++){
		cout<<t[i]<<' ';
	}
}

最后完结撒花!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值