杂项/2018 年刑侦科推理试题
2018 年江苏网警在微博上公布了一套 2018 年刑侦科目推理试题, 试题如下:
1. 这道题的答案是:
A.A B.B C.C D.D
2. 第 5 题的答案是:
A.C B.D C.A D.B
3. 以下选项中哪一题的答案与其他三项不同:
A.第 3 题 B.第 6 题 C.第 2 题 D.第 4 题
4. 以下选项中哪两项的答案相同:
A.第 1,5 题 B. 第 2,7 题 C. 第 1,9 题 D. 第 6,10 题
5. 以下选项中哪一题的答案与本题相同:
A.第 8 题 B. 第 4 题 C. 第 9 题 D. 第 7 题
6. 以下选项中哪两题的答案与第 8 题相同:
A.第 2,4 题 B. 第 1,6 题 C. 第 3,10 题 D. 第 5,9 题
7. 在此十道题中, 被选中次数最少的选项字母为:
A.C B.B C.A D.D
8. 以下选项中哪一题的答案与第一题的答案在字母中不相邻:
A.第 7 题 B. 第 5 题 C. 第 2 题 D. 第 10 题
9. 已知"第 1 题与第 6 题的答案相同"与"第 X 题与第 5 题的答案相同"的真假性相反, 那么 X 为:
A.第 6 题 B. 第 10 题 C. 第 2 题 D. 第 9 题
10. 在此 10 道题中, ABCD 四个字母出现最多与最少者的差为:
A.3 B.2 C.4 D.1
在看到这道题的时候我大概想好了要怎么使用计算机去解决. 可惜的是当时人在户外, 卫生纸太小写不下. 第二天回到家, 用时 33 分钟编写了如下程序并搜索到了唯一解. 在计算机的角度来看, 这道题的求解空间是 4^10
即 1 兆, 是相当小的一个数字. 约束条件是 10 个, 即 10 道题目. 因此, 只需要遍历 0 到 4^10 并查找满足 10 个约束条件的数字即可. 代码如下:
package main
import (
"log"
"slices"
)
func constraint_1(_ [10]uint8) bool {
return true
}
func constraint_2(v [10]uint8) bool {
switch v[1] {
case 0:
return v[4] == 2
case 1:
return v[4] == 3
case 2:
return v[4] == 0
case 3:
return v[4] == 1
}
panic("unreachable")
}
func constraint_3(v [10]uint8) bool {
switch v[2] {
case 0:
return v[2] != v[5] && v[5] == v[1] && v[1] == v[3]
case 1:
return v[5] != v[2] && v[2] == v[1] && v[1] == v[3]
case 2:
return v[1] != v[2] && v[2] == v[5] && v[5] == v[3]
case 3:
return v[3] != v[2] && v[2] == v[5] && v[5] == v[1]
}
panic("unreachable")
}
func constraint_4(v [10]uint8) bool {
switch v[3] {
case 0:
return v[0] == v[4]
case 1:
return v[1] == v[6]
case 2:
return v[0] == v[8]
case 3:
return v[5] == v[9]
}
panic("unreachable")
}
func constraint_5(v [10]uint8) bool {
switch v[4] {
case 0:
return v[4] == v[7]
case 1:
return v[4] == v[3]
case 2:
return v[4] == v[8]
case 3:
return v[4] == v[6]
}
panic("unreachable")
}
func constraint_6(v [10]uint8) bool {
switch v[5] {
case 0:
return v[1] == v[3] && v[3] == v[7]
case 1:
return v[0] == v[5] && v[5] == v[7]
case 2:
return v[2] == v[9] && v[9] == v[7]
case 3:
return v[4] == v[8] && v[8] == v[7]
}
panic("unreachable")
}
func constraint_7(v [10]uint8) bool {
c := [4]uint8{}
for _, e := range v {
c[e] += 1
}
switch v[6] {
case 0:
return c[2] < c[0] && c[2] < c[1] && c[2] < c[3]
case 1:
return c[1] < c[0] && c[1] < c[2] && c[1] < c[3]
case 2:
return c[0] < c[1] && c[0] < c[2] && c[0] < c[3]
case 3:
return c[3] < c[0] && c[3] < c[1] && c[3] < c[2]
}
panic("unreachable")
}
func constraint_8(v [10]uint8) bool {
switch v[7] {
case 0:
return v[6]-v[0] != 1 && v[6]-v[0] != 255
case 1:
return v[4]-v[0] != 1 && v[4]-v[0] != 255
case 2:
return v[1]-v[0] != 1 && v[1]-v[0] != 255
case 3:
return v[9]-v[0] != 1 && v[9]-v[0] != 255
}
panic("unreachable")
}
func constraint_9(v [10]uint8) bool {
switch v[8] {
case 0:
a := v[0] == v[5]
b := v[5] == v[4]
return a == !b
case 1:
a := v[0] == v[5]
b := v[9] == v[4]
return a == !b
case 2:
a := v[0] == v[5]
b := v[1] == v[4]
return a == !b
case 3:
a := v[0] == v[5]
b := v[8] == v[4]
return a == !b
}
panic("unreachable")
}
func constraint_a(v [10]uint8) bool {
c := [4]uint8{}
for _, e := range v {
c[e] += 1
}
switch v[9] {
case 0:
return slices.Max(c[:])-slices.Min(c[:]) == 3
case 1:
return slices.Max(c[:])-slices.Min(c[:]) == 2
case 2:
return slices.Max(c[:])-slices.Min(c[:]) == 4
case 3:
return slices.Max(c[:])-slices.Min(c[:]) == 1
}
panic("unreachable")
}
func main() {
v := [10]uint8{}
for i := 0; i < 1048576; i++ {
for j := 0; j < 10; j++ {
v[j] = uint8((i >> (j * 2)) & 3)
}
if !constraint_1(v) {
continue
}
if !constraint_2(v) {
continue
}
if !constraint_3(v) {
continue
}
if !constraint_4(v) {
continue
}
if !constraint_5(v) {
continue
}
if !constraint_6(v) {
continue
}
if !constraint_7(v) {
continue
}
if !constraint_8(v) {
continue
}
if !constraint_9(v) {
continue
}
if !constraint_a(v) {
continue
}
log.Println(v)
}
}
计算得到答案是 BCACA CDABA
.