Node.js力破江苏网警刑侦科推理试题

月前,江苏网警 在微博发布了一套《2018年刑侦科目推理试题》,可谓难倒了诸多英雄好汉,评论区内更是一片皮皮之音。

不过当这事传入了程序猿族的耳中,画风顿时突变,Java、Python、PHP 等各派英雄纷纷使出门派语言,以 枚举法 之小小智谋便破解了江苏网警这 刑侦推理 之阵。

我等前端后生亦不甘落后,于是 便有了今天 这一 《Node.js力破江苏网警刑侦科推理试题》一说。

话不多说,先上图:

交出代码,以示清白:

question.js

/**
 * Created by lonelydawn at 2018-03-29.
 */
var options = ['A', 'B', 'C', 'D']
// 定义题目答案数组,数组首个元素设置为空, 以偏移数组下标和题号对齐
var answers = [, 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A']
var result = []
/** 
 * 01. 这道题的答案是
 * A. A    B. B    C. C    D. D
 */

/**
 * 02. 第5题的答案是
 * A. C    B. D    C. A    D. B
 */
var getQues02 = function (answers) {
	if (answers[5] === 'C') {
		return 'A'
	} else if (answers[5] === 'D') {
		return 'B'
	} else if (answers[5] === 'A') {
		return 'C'
	} else if (answers[5] === 'B') {
		return 'D'
	}
	return -1
}

/**
 * 03. 以下哪一题答案与其他三项不同
 * A. 第3题    B. 第6题    C. 第2题    D. 第4题
 */
var getQues03 = function (answers) {
	if (answers[3] !== answers[6] && answers[3] !== answers[2]
			&& answers[3] !== answers[4]) {
		return 'A'
	} else if (answers[6] !== answers[3] && answers[6] !== answers[2]
			&& answers[6] !== answers[4]) {
		return 'B'
	} else if (answers[2] !== answers[3] && answers[2] !== answers[6]
			&& answers[2] !== answers[4]) {
		return 'C'
	} else if (answers[4] !== answers[3] && answers[4] !== answers[6]
			&& answers[4] !== answers[2]) {
		return 'D'
	}
	return -1
}

/**
 * 04. 以下选项中哪两题答案相同
 * A. 第1,5题    B. 第2,7题    C. 第1,9题     D. 第6,10题
 */
var getQues04 = function (answers) {
	if (answers[1] === answers[5]) {
		return 'A'
	} else if (answers[2] === answers[7]) {
		return 'B'
	} else if (answers[1] === answers[9]) {
		return 'C'
	} else if (answers[6] === answers[10]) {
		return 'D'
	}
	return -1
}

/**
 * 05. 以下选项中哪一题答案与本题相同
 * A. 第8题    B. 第4题    C. 第9题     D. 第7题
 */
var getQues05 = function (answers) {
	if (answers[8] === 'A') {
		return 'A'
	} else if (answers[4] === 'B') {
		return 'B'
	} else if (answers[9] === 'C') {
		return 'C'
	} else if (answers[7] === 'D') {
		return 'D'
	}
	return -1
}

/**
 * 06. 以下选项中哪两题的答案与第八题相同
 * A. 第2,4题    B. 第1,6题    C. 第3,10题     D. 第5,9题
 */
var getQues06 = function (answers) {
	if (answers[8] === answers[2] && answers[8] === answers[4]) {
		return 'A'
	} else if (answers[8] === answers[1] && answers[8] === answers[6]) {
		return 'B'
	} else if (answers[8] === answers[3] && answers[8] === answers[10]) {
		return 'C'
	} else if (answers[8] === answers[5] && answers[8] === answers[9]) {
		return 'D'
	}
	return -1
}
/**
 * 07. 在此十道题中,被选中次数最少的选项字母为
 * A. C    B. B    C. A     D. D
 */
var getQues07 = function (answers) {
	var counter = [0, 0, 0, 0]
	answers.forEach(function (answer) {
		options.forEach(function (option, index) {
			if (answer === option) {
				counter[index]++
			}
		})
	})
	return options[counter.indexOf(Math.min(counter[0], counter[1], counter[2], counter[3]))]
}
/**
 * 08. 以下选项中哪一题的答案与第一题的答案在字母中不相邻
 * A. 第7题    B. 第5题    C. 第2题     D. 第10题
 * 解: A、B、C、D 四个字母,先列出每个字母不相邻的都有哪些,再进行判断
 * PS: 这题可能出现多解,但由于试题明确地标注了“单项选择”,因此只取第一个
 */
var getQues08 = function (answers) {
	var notNeighbor = {
		A: ['C', 'D'],
		B: ['D'],
		C: ['A'],
		D: ['A', 'B']
	}[answers[1]]
	if (notNeighbor.indexOf(answers[7]) > -1) {
		return 'A'
	} else if (notNeighbor.indexOf(answers[5]) > -1) {
		return 'B'
	} else if (notNeighbor.indexOf(answers[2]) > -1) {
		return 'C'
	} else if (notNeighbor.indexOf(answers[10]) > -1) {
		return 'D'
	}
	return -1
}
/**
 * 09. 已知"第一题与第六题的答案相同"与"第X题与第5题的答案相同"的真假性
 * A. 第6题    B. 第10题    C. 第2题     D. 第9题
 * 解: 
 * 题干意思简单来说就是: 第X题答案可能与第5题相同,也可能不同, 
 * 因此我们分两种情况进行判断
 * PS: 
 * 如果第一题和第六题答案相同,则X与5答案不相同,X的答案有多个取值可能(A/B/C/D)
 * 如果不同,则x与5答案相同,X的答案只能取唯一值
 * 但即使X的答案取值唯一,X也有多个取值可能(1-10)
 * 我将这些取值的候选数组和题目的4个选项取交集,从而可以限定出唯一 X 值
 */
var getQues09 = function (answers) {
	var arr = []
	var x = -1
	if (answers[1] === answers[6]) {
		for (var i = 0; i < answers.length; i++) {
			if (i !== 5 && answers[i] !== answers[5]) {
				var answer = ['A', 'B', 'C', 'D'][[6, 10, 2, 9].indexOf(i)]
				if (answer) {
					return answer
				}
			}
		}
	} else {
		for (var i = 0; i < answers.length; i++) {
			if (i !== 5 && answers[i] === answers[5]) {
				var answer = ['A', 'B', 'C', 'D'][[6, 10, 2, 9].indexOf(i)]
				if (answer) {
					return answer
				}
			}
		}
	}
}
/**
 * 10. 在此10道题中, ABCD四个字母出现次数最多与最少者的差为
 * A. 3    B. 2    C. 4     D. 1
 */
var getQues10 = function (answers) {
	var counter = [0, 0, 0, 0]
	answers.forEach(function (answer) {
		options.forEach(function (option, index) {
			if (answer === option) {
				counter[index]++
			}
		})
	})
	var max = Math.max(counter[0], counter[1], counter[2], counter[3])
	var min = Math.min(counter[0], counter[1], counter[2], counter[3])
	return {
		1: 'D',
		2: 'B',
		3: 'A',
		4: 'C'
	}[max - min]
}

// 递归 + 循环 建立枚举队列
var recurse = function (answers, index) {
	var answers = JSON.parse(JSON.stringify(answers))
	if (index < 10) {
		for (var i = 0; i < options.length; i++) {
			answers[index] = options[i]
			recurse(answers, index + 1)
			if (getQues02(answers) !== answers[2]) {
				continue
			}
			if (getQues03(answers) !== answers[3]) {
				continue
			}
			if (getQues04(answers) !== answers[4]) {
				continue
			}
			if (getQues05(answers) !== answers[5]) {
				continue
			}
			if (getQues06(answers) !== answers[6]) {
				continue
			}
			if (getQues07(answers) !== answers[7]) {
				continue
			}
			if (getQues08(answers) !== answers[8]) {
				continue
			}
			if (getQues09(answers) !== answers[9]) {
				continue
			}
			if (getQues10(answers) !== answers[10]) {
				continue
			}
			result = JSON.parse(JSON.stringify(answers))
		}
	}
}

var begin = new Date().getTime()
recurse(answers, 1)
console.log('\nresult:', result.length > 0 ? result.slice(1, result.length) : 'none')
console.log('time:', (new Date().getTime() - begin) / 1000 + 's')

PS: 一切尽在注释中,如感兴趣,欢迎评论。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博客

设计模式之前奏(UML类图)

本人菜菜一个,最近一直在博客园游走闲逛,看到了各种技术,各种各种……。便看到了大话设计模式这本书,下了电子版的看了看第一章,感觉相当不错,不仅通俗易懂,而且与实...

2213
来自专栏HansBug's Lab

3361: [Usaco2004 Jan]培根距离

3361: [Usaco2004 Jan]培根距离 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 16  S...

3555
来自专栏ml

hdu-----(4514)湫湫系列故事——设计风景线(树形DP+并查集)

湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/3276...

3878
来自专栏玄魂工作室

56行Python代码实现身份证字典生成器

最近过生日,女朋友送了几本Python黑客编程的书(没错,小黑阔也是可以有女朋友的)。哈哈,皮一下就是很开心。

3613
来自专栏ACM算法日常

HDU6370:Werewolf 推理+拓扑排序 2018第六场杭电多校

"The Werewolves" is a popular card game among young people.In the basic game, th...

702
来自专栏tkokof 的技术,小趣及杂念

侃侃哈希表

说到哈希表,相信初通数据结构的人士应该耳熟能详,其相关的结构细节虽然并不繁复,但就快速查找数据而言,该结构优异的性能表现绝对可算一枝独秀,平均情况下O(1)的时...

771
来自专栏写代码的海盗

乐呵乐呵得了 golang入坑系列

开场就有料,今天返回去看了看以前的文章,轻松指数有点下降趋势。一琢磨,这不是我的风格呀。一反思,合着是这段时间,脑子里杂七杂八的杂事有点多,事情一多,就忘了快乐...

3485
来自专栏C语言及其他语言

OJ系统(ACM/NOI)的基本输入输出教程

在介绍OJ系统之前,首先为大家介绍一下ACM: ACM原代表美国计算机协会,因其举办的ICPC即国际大学生程序设计竞赛而闻名全世界,此项赛事要求学生的在五小时内...

51612
来自专栏Java帮帮-微信公众号-技术文章全总结

【学习经验】Java中常用英文

【学习经验】Java中常用英文 第一章: public['pʌblik] 公共的,公用的 static['stætik] 静的;静态的...

36610
来自专栏Java帮帮-微信公众号-技术文章全总结

秒懂,Java 注解 (Annotation)你可以这样学【面试+工作】

这处图片引自老罗的博客。为了避免不必要的麻烦,首先声明我个人比较尊敬老罗的。至于为什么放这张图,自然是为本篇博文服务,接下来我自会说明。好了,可以开始今天的博...

3713

扫码关注云+社区

领取腾讯云代金券