一道有趣的推理题

今天信息课,老师给了我们一道推理题,用代码实现

在这里插入图片描述
第一次接触这类题,脑子顿时没有思路
于是,我就模拟小学做这类问题的方法——假设第一题选A,第二题选A……
我突然想到,可以暴力枚举每一道题答案,然后再判断是否合法
于是

#define reg(x) for(x='A';x<='D';x++)

然后

reg(a1) reg(a2) reg(a3) reg(a4) reg(a5)
reg(a6) reg(a7) reg(a8) reg(a9) reg(a10)
if(work()) cout << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10 << "\n";

再判断每一题是否合法

bool work(){
	//第一题没有限制,就不用考虑了
	if(work2()) return 0;
	if(work3()) return 0;
	if(work4()) return 0;
	if(work5()) return 0;
	if(work6()) return 0;
	if(work7()) return 0;
	if(work8()) return 0;
	if(work9()) return 0;
	if(work10())return 0;
	return 1;
}

对于第二题,我们只需判断第二题和第五题的答案是否对应

bool work2(){
	if(a2 == 'A' && a5 == 'C') return 0;
	if(a2 == 'B' && a5 == 'D') return 0;
	if(a2 == 'C' && a5 == 'A') return 0;
	if(a2 == 'D' && a5 == 'B') return 0;
	return 1;
}

对于第三题,判断选项中的答案是否与其他三个不同,且其他三个选项的答案是否相同

bool work3(){
	if(a3 == 'A'){
		if(a6 == a3) return 1;
		if(a6 != a2) return 1;
		if(a6 != a4) return 1;
	}
	if(a3 == 'B'){
		if(a3 == a6) return 1;
		if(a4 != a3) return 1;
		if(a2 != a3) return 1; 
	}
	if(a3 == 'C'){
		if(a2 == a3) return 1;
		if(a4 != a3) return 1;
		if(a6 != a3) return 1;
	}
	if(a3 == 'D'){
		if(a3 == a4) return 1;
		if(a2 != a3) return 1;
		if(a6 != a3) return 1;
	}
	return 0;
}

第四题也是,照题模拟即可

bool work4(){
	switch(a4){
		case 'A':
			if(a1 == a5) return 0;
			break;
		case 'B':
			if(a2 == a7) return 0;
			break;
		case 'C':
			if(a1 == a9) return 0;
			break;
		case 'D':
			if(a6 == a10) return 0;
			break;
	}
	return 1;
}

第五题直接判断选项的题目是否与本题答案相同

bool work5(){
	switch(a5){
		case 'A':
			if(a5 != a8) return 1;
			break;
		case 'B':
			if(a4 != a5) return 1;
			break;
		case 'C':
			if(a5 != a9) return 1;
			break;
		case 'D':
			if(a5 != a7) return 1;
			break;
	}
	return 0;
}

第六题同理

bool work6(){
	switch(a6){
		case 'A':
			if(a2 != a8) return 1;
			if(a4 != a8) return 1;
			break;
		case 'B':
			if(a1 != a8) return 1;
			if(a6 != a8) return 1;
			break;
		case 'C':
			if(a3 != a8) return 1;
			if(a10 != a8) return 1;
			break;
		case 'D':
			if(a5 != a8) return 1;
			if(a9 != a8) return 1;
			break;
	}
	return 0;
}

第七题可以将每个选项被选的次数统计起来,再找出次数最小的

bool work7(){
	memset(s,0,sizeof(s));//记得初始化
	s[a1-'A']++; s[a2-'A']++; s[a3-'A']++; s[a4-'A']++; s[a5-'A']++;
	s[a6-'A']++; s[a7-'A']++; s[a8-'A']++; s[a9-'A']++; s[a10-'A']++; 
	char f;
	int minn = 999;
	for(int i=0;i<4;i++)
		if(s[i] < minn) minn = s[i],f = 'A'+i;
	if(a7 == 'A' && f == 'C') return 0;
	if(a7 == 'B' && f == 'B') return 0;
	if(a7 == 'C' && f == 'A') return 0;
	if(a7 == 'D' && f == 'D') return 0;
	return 1;
}

对于第八题,将两道题选项字母的ASCII码相减,取绝对值,判断是否为一

inline bool work8_pd(char a){
	if(abs(a-a1) == 1) return 1;
	return 0;
}
bool work8(){
	switch(a8){
		case 'A':
			if(work8_pd(a7)) return 1;
			break;
		case 'B':
			if(work8_pd(a5)) return 1;
			break;
		case 'C':
			if(work8_pd(a2)) return 1;
			break;
		case 'D':
			if(work8_pd(a10)) return 1;
			break;
	}
	return 0;
}

第九题也是模拟

bool work9(){
	char a;
	if(a9 == 'A') a = a6;
	if(a9 == 'B') a = a10;
	if(a9 == 'C') a = a2;
	if(a9 == 'D') a = a9;
	bool f1 = (a1 == a6),f2 = (a == a5);
	return f1==f2;//ATTENTION
}

最后一题可以统计每一个选项出现次数,然后排序,用最大减最小

bool work10(){
	memset(s,0,sizeof(s));
	s[a1-'A']++; s[a2-'A']++; s[a3-'A']++; s[a4-'A']++; s[a5-'A']++;
	s[a6-'A']++; s[a7-'A']++; s[a8-'A']++; s[a9-'A']++; s[a10-'A']++; 
	sort(s,s+4);//STL真香
	int f = s[3]-s[0];
	int a;
	if(a10 == 'A') a = 3;
	if(a10 == 'B') a = 2;
	if(a10 == 'C') a = 4;
	if(a10 == 'D') a = 1;
	if(a == f) return 0;
	return 1;
}

再把他们合起来

#include<bits/stdc++.h>
#define reg(x) for(x='A';x<='D';x++)
#define ll long long
#define ull unsigned long long
using namespace std;
char a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;
int s[10];
bool work2(){
	if(a2 == 'A' && a5 == 'C') return 0;
	if(a2 == 'B' && a5 == 'D') return 0;
	if(a2 == 'C' && a5 == 'A') return 0;
	if(a2 == 'D' && a5 == 'B') return 0;
	return 1;
}
bool work3(){
	if(a3 == 'A'){
		if(a6 == a3) return 1;
		if(a6 != a2) return 1;
		if(a6 != a4) return 1;
	}
	if(a3 == 'B'){
		if(a3 == a6) return 1;
		if(a4 != a3) return 1;
		if(a2 != a3) return 1; 
	}
	if(a3 == 'C'){
		if(a2 == a3) return 1;
		if(a4 != a3) return 1;
		if(a6 != a3) return 1;
	}
	if(a3 == 'D'){
		if(a3 == a4) return 1;
		if(a2 != a3) return 1;
		if(a6 != a3) return 1;
	}
	return 0;
}
bool work4(){
	switch(a4){
		case 'A':
			if(a1 == a5) return 0;
			break;
		case 'B':
			if(a2 == a7) return 0;
			break;
		case 'C':
			if(a1 == a9) return 0;
			break;
		case 'D':
			if(a6 == a10) return 0;
			break;
	}
	return 1;
}
bool work5(){
	switch(a5){
		case 'A':
			if(a5 != a8) return 1;
			break;
		case 'B':
			if(a4 != a5) return 1;
			break;
		case 'C':
			if(a5 != a9) return 1;
			break;
		case 'D':
			if(a5 != a7) return 1;
			break;
	}
	return 0;
}
bool work6(){
	switch(a6){
		case 'A':
			if(a2 != a8) return 1;
			if(a4 != a8) return 1;
			break;
		case 'B':
			if(a1 != a8) return 1;
			if(a6 != a8) return 1;
			break;
		case 'C':
			if(a3 != a8) return 1;
			if(a10 != a8) return 1;
			break;
		case 'D':
			if(a5 != a8) return 1;
			if(a9 != a8) return 1;
			break;
	}
	return 0;
}
bool work7(){
	memset(s,0,sizeof(s));
	s[a1-'A']++; s[a2-'A']++; s[a3-'A']++; s[a4-'A']++; s[a5-'A']++;
	s[a6-'A']++; s[a7-'A']++; s[a8-'A']++; s[a9-'A']++; s[a10-'A']++; 
	char f;
	int minn = 999;
	for(int i=0;i<4;i++)
		if(s[i] < minn) minn = s[i],f = 'A'+i;
	if(a7 == 'A' && f == 'C') return 0;
	if(a7 == 'B' && f == 'B') return 0;
	if(a7 == 'C' && f == 'A') return 0;
	if(a7 == 'D' && f == 'D') return 0;
	return 1;
}
inline bool work8_pd(char a){
	if(abs(a-a1) == 1) return 1;
	return 0;
}
bool work8(){
	switch(a8){
		case 'A':
			if(work8_pd(a7)) return 1;
			break;
		case 'B':
			if(work8_pd(a5)) return 1;
			break;
		case 'C':
			if(work8_pd(a2)) return 1;
			break;
		case 'D':
			if(work8_pd(a10)) return 1;
			break;
	}
	return 0;
}
bool work9(){
	char a;
	if(a9 == 'A') a = a6;
	if(a9 == 'B') a = a10;
	if(a9 == 'C') a = a2;
	if(a9 == 'D') a = a9;
	bool f1 = (a1 == a6),f2 = (a == a5);
	return f1==f2;
}
bool work10(){
	memset(s,0,sizeof(s));
	s[a1-'A']++; s[a2-'A']++; s[a3-'A']++; s[a4-'A']++; s[a5-'A']++;
	s[a6-'A']++; s[a7-'A']++; s[a8-'A']++; s[a9-'A']++; s[a10-'A']++; 
	sort(s,s+4);
	int f = s[3]-s[0];
	int a;
	if(a10 == 'A') a = 3;
	if(a10 == 'B') a = 2;
	if(a10 == 'C') a = 4;
	if(a10 == 'D') a = 1;
	if(a == f) return 0;
	return 1;
}
bool work(){
	if(work2()) return 0;
	if(work3()) return 0;
	if(work4()) return 0;
	if(work5()) return 0;
	if(work6()) return 0;
	if(work7()) return 0;
	if(work8()) return 0;
	if(work9()) return 0;
	if(work10())return 0;
	return 1;
}
int main(){
	reg(a1) reg(a2) reg(a3) reg(a4) reg(a5)
	reg(a6) reg(a7) reg(a8) reg(a9) reg(a10)
	if(work()) cout << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10 << "\n";
	return 0;
}

再运行
在这里插入图片描述
然后这题就AC了

话说那些刑侦考试时是怎么做出来的

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值