这段时间各种社交群和朋友圈火起来一个刑侦推理题, 这是 3 月 1 日 @江苏网警在微博上发布了一套试题看了两眼觉得推理太麻烦, 试试代码群举出答案看看原题如图
微信图片_20180303124123.jpg
一些简单的可行性分析
10 道题, 每个题四个群举次数 4 的 10 次方虽然时间复杂度 O(n^10) 还好 n 是 40.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:
- // 判断第 14 题答案是否与第 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;
- }
- // 由于第 710 题问题是同类型的, 所以一块计算 start
- int[] check10 = new int[5];
- // 把每个题的答案 (1234) 作为新数组下表, 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;
- }
- // 第 710 题校验 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();
- }
运行结果:
- 2
- 3
- 1
- 3
- 1
- 3
- 4
- 1
- 2
- 1
转化成答案是:
BCACA
CDABA
总结:
这个方法只适合题个数少的, 如果题目较多则需要考虑多线程解决类似的推理题由于解题需要顺序, 所以硬编码方法只能用群举的方案暂时只能想到这了, 如果那位大神有更好的方案欢迎交流
来源: http://www.jianshu.com/p/efbf853c1ea7