2018刑侦推理 java_java代码解“2018年刑侦科推理试题”

这段时间各种社交群和朋友圈火起来一个刑侦推理题,这是 3月1日“@江苏网警”在微博上发布了一套试题。看了两眼觉得推理太麻烦,试试代码群举出答案看看。原题如图

efbf853c1ea7?from=singlemessage

微信图片_20180303124123.jpg

一些简单的可行性分析

10道题,每个题四个群举次数4的10次方。虽然时间复杂度O(n^10) 还好n是4。0.0迷之尴尬……

java代码

public static void answer(){

//用1234分别对应ABCD,计算方便

int[] answers = {1,2,3,4};

//群举答案

for (int q1 : answers) {

for (int q2 : answers) {

for (int q3 : answers) {

for (int q4 : answers) {

for (int q5 : answers) {

for (int q6 : answers) {

for (int q7 : answers) {

for (int q8 : answers) {

for (int q9 : answers) {

for (int q10 : answers) {

int[] questions = new int[10];

questions[0] = q1;

questions[1] = q2;

questions[2] = q3;

questions[3] = q4;

questions[4] = q5;

questions[5] = q6;

questions[6] = q7;

questions[7] = q8;

questions[8] = q9;

questions[9] = q10;

if (isEnd(questions)){

//遍历输出符合条件的答案

for (int i = 0 ; i < 10; i++){

System.out.println((i+1) + ":" + questions[i]);

}

}

}

}

}

}

}

}

}

}

}

}

}

/**

*判断每个答案是否符合题意

*为了方便questions数组中从0开始,

*题目比数组角标多1(不要问为什么,奏是这么开)

*比如question[0] 的值表示第1题答案

**/

static boolean isEnd(int[] questions){

//第二题,第5题的答案是

switch (questions[4]){

case 1:

//如果第5题答案是A,判断第2题答案是不是C。不是返回false,是继续

if(questions[1] != 3)

return false;

break;

case 2:

//原理同上

if(questions[1] != 4)

return false;

break;

case 3:

//原理同上

if(questions[1] != 1)

return false;

break;

case 4:

//原理同上

if(questions[1] != 2)

return false;

break;

}

//第3题,以下选项中哪一题的答案与其他三项不同

switch (questions[2]){

case 1:

if(!(questions[2]!=questions[5] && questions[5]==questions[1] && questions[1] == questions[3]))

return false;

break;

case 2:

if(!(questions[5]!=questions[2] && questions[2]==questions[1] && questions[1] == questions[3]))

return false;

break;

case 3:

if(!(questions[1]!=questions[5] && questions[2]==questions[5] && questions[5] == questions[3]))

return false;

break;

case 4:

if(!(questions[3]!=questions[5] && questions[5]==questions[1] && questions[1] == questions[2]))

return false;

break;

}

//第4题,以下选项中那两题的答案相同

switch (questions[3]){

case 1:{

//判断第1题与第5题答案是否相同

if (questions[0] != questions[4]){

return false;

}

break;

}

case 2:{

//原理同上

if (questions[1] != questions[6]){

return false;

}

break;

}

case 3:{

//原理同上

if (questions[0] != questions[8]){

return false;

}

break;

}

case 4:{

//原理同上

if (questions[5] != questions[9]){

return false;

}

break;

}

}

//第5题,以下选项中哪一题的答案与本题相同

switch (questions[4]){

case 1:

//判断第8题答案是否是A

if (questions[7] != 1)

return false;

break;

case 2:

//原理同上

if(questions[3] != 2)

return false;

break;

case 3:

//原理同上

if (questions[8] != 3)

return false;

case 4:

//原理同上

if (questions[6] != 4)

return false;

break;

}

//第6题,以下选项中哪两题的答案与第8题相同

switch (questions[5]){

case 1:

//判断第1、4题答案是否与第8题答案相同

if(questions[1] != questions[7] || questions[4] != questions[7])

return false;

break;

case 2:

//原理同上

if(questions[0] != questions[7] || questions[5] != questions[7])

return false;

break;

case 3:

//原理同上

if(questions[2] != questions[7] || questions[9] != questions[7])

return false;

break;

case 4:

//原理同上

if(questions[4] != questions[7] || questions[8] != questions[7])

return false;

break;

}

//由于第7、10题问题是同类型的,所以一块计算 。start

int[] check10 = new int[5];

//把每个题的答案(1、2、3、4)作为新数组下表,value++计算出现次数

for (int i=0;i < questions.length;i++){

check10[questions[i]]++;

}

//出现最少与最多选项的次数初始化为A的次数

int low = check10[1];

int longer = check10[1];

//出现最少的选项,初始化为A

int lowA = 1;

//最少与最多次数的选项相关计算

for (int i=1;i<5;i++) {

if(check10[i] >0 && check10[i] < low){

low = check10[i];

lowA = i;

}

if (check10[i] > longer){

longer = check10[i];

}

}

//第7题,在此十道题中,被选中次数最少的选项字母为

switch (questions[6]){

case 1:

//判断才出现最少的字母是否为C

if (lowA != 3)

return false;

break;

case 2:

//原理同上

if (lowA != 2)

return false;

break;

case 3:

//原理同上

if (lowA != 1)

return false;

break;

case 4:

//原理同上

if (lowA != 4)

return false;

break;

}

//第10题,在此10道题中,ABCD四个字母出现次数最多与最少者的差为

//最多次数与最少次数的差值

int t = longer-low;

switch (questions[9]){

case 1:

//判断差值是否为3

if (t != 3)

return false;

break;

case 2:

//原理同上

if (t != 2)

return false;

break;

case 3:

//原理同上

if (t != 4)

return false;

break;

case 4:

//原理同上

if (t != 1)

return false;

break;

}

//第7、10 题校验end

//第8题,以下选项中哪一题的答案与第1题的答案在字母中不相邻

switch (questions[7]) {

case 1:

//判断第7题与第一题答案差值绝对是是否为1

if (Math.abs(questions[6] - questions[0]) == 1)

return false;

break;

case 2:

//原理同上

if (Math.abs(questions[4] - questions[0]) == 1)

return false;

break;

case 3:

//原理同上

if (Math.abs(questions[1] - questions[0]) == 1)

return false;

break;

case 4:

//原理同上

if (Math.abs(questions[9] - questions[0]) == 1)

return false;

break;

}

//第9题,已知“第1题与第6题的答案相同”与“第X题与第5题的答案相同”的真假性相反,那么X为

//判断第1题与第6题的答案是否相同

boolean isOne = questions[0]==questions[5]?true:false;

switch (questions[8]){

case 1:

if(isOne){

//第1题与第6题相同,第6题与第5题答案相同返回false;

if (questions[5] == questions[4])

return false;

}else {

//第1题与第6题不相同,第6题与第5题答案不相同返回false;

if (questions[5] != questions[4])

return false;

}

break;

case 2:

//原理同上

if(isOne){

if (questions[9] == questions[4])

return false;

}else {

if (questions[9] != questions[4])

return false;

}

break;

case 3:

//原理同上

if(isOne){

if (questions[1] == questions[4])

return false;

}else {

if (questions[1] != questions[4])

return false;

}

break;

case 4:

//原理同上

if(isOne){

if (questions[8] == questions[4])

return false;

}else {

if (questions[8] != questions[4])

return false;

}

break;

}

return true;

}

public static void main(String[] args) {

answer();

}

运行结果:

1:2

2:3

3:1

4:3

5:1

6:3

7:4

8:1

9:2

10:1

转化成答案是:

B、C、A、C、A

C、D、A、B、A

总结:

这个方法只适合题个数少的,如果题目较多则需要考虑多线程解决。类似的推理题由于解题需要顺序,所以硬编码方法只能用群举的方案。暂时只能想到这了,如果那位大神有更好的方案欢迎交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值