玩具九 发表于 2021-2-13 23:06:52

2018年刑侦推理试题解答

2018年刑侦推理试题:


此题一出,吓退了一大批原本还对刑侦专业跃跃欲试的各路英雄好汉。这组题目应该如何入手呢?还是先给答案,再来细说解题思路好了。
答案



解题思路

以此题为例,做一个简单的python小教程。
提取"第x题的答案"

首先,观察到题目中经常出现的说法是:“第x题的答案”怎样怎样,那么常用的一个过程就是要提取第x题的答案。
在python中可以使用的一个数据结构叫作列表list。列表是使用[ ]括起来的一些元素,要提取其中的内容,用列表名[序号]就可以提取了。比如
In :
sample= # “#”号后面的部分是注释,不会进入计算,我后面会在程序中使用注释说明
sample # 注意python的计数是从第0项开始的,所以第2项是2.3而不是1.2
Out:
2.3
如果用数字0、1、2、3来表示ABCD的话,就可以把所有的答案放进一个列表里。提取某一题的答案,就是提取列表中的第几项。注意python的列表是从第0项开始计数的,为了读题中不引起混淆, 我将列表的第0项设定成空项.
In :
# 举例,假设第1题到第5题的答案分别是AABDC,用0、1、2、3来表示ABCD
sample_answer=
# 提取第3题的答案
sample_answer
Out:
1
第1题

这道题的答案是:
       
[*]A.A       
[*]B.B       
[*]C.C       
[*]D.D
题目中没有给出限定,所以暂时先不管它。
第2题

第5题的答案是:
       
[*]A.C       
[*]B.D       
[*]C.A       
[*]D.B
在第2题里,如何描述A->C,B->D,C->A,D->B的映射关系呢?可以用一个python数据结构,叫作字典。字典是用{ }括起来的一组元素,每一个元素里有一个key:value的数据对,表示从key到value的映射。
要表示A->C,B->D,C->A,D->B的映射关系,可以建立一个字典:
In :
a2_dict={0:2,# A.C
             1:3,# B.D
             2:0,# C.A
             3:2}# D.B
a2_dict # 字典内容的提取,是使用字典名,就可以提取出value
Out:
3
用0,1,2,3代表ABCD
       
[*]如果第二题选A,那么就是说第5题的答案是C,也就是a2_dict的值2       
[*]如果第二题选B,那么就是说第5题的答案是D,也就是a2_dict的值3       
[*]如果第二题选C,那么就是说第5题的答案是A,也就是a2_dict的值0       
[*]如果第二题选D,那么就是说第5题的答案是B,也就是a2_dict的值2
假定我们已经知道了所有的答案,放在answer这个列表里,那么第2题的答案是answer,第5题的答案是answer,那么第2题的答案所对应的值就是a2_dict[ answer ],判断第2题是不是做对了, 就要看
a2_dict[ answer ]==answer
是真还是假。
我将这个判断过程写成一个“函数”,这个函数负责看第2题是否做对了。Python的函数定义是用
def 函数名(参数表):
   空4格写函数内容
   return 返回结果
In :
def test2(answer):
   a2_dict={0:2,# A.C
                  1:3,# B.D
                  2:0,# C.A
                  3:2}# D.B
   return a2_dict[ answer ]==answer
In :
# 一般写好一个函数,应当测试一下是否写对了。
print(test2()) # 应当为假
print(test2()) # 应当为真,假定第2题的答案是0,对应第5题的答案是2
False True
第3题

以下选项中哪一题的答案与其他三项不同:
       
[*]A. 第3题       
[*]B. 第6题       
[*]C. 第2题       
[*]D. 第4题
当然我们可以去一个一个比对,但python中对列表有一个简单的判断命令叫in,如果元素在这个列表中,那么in命令就返回真,否则为假。
如果把第3题、第6题、第2题、第4题的答案放在一个列表中,那么有
a3_list=[ answer, answer, answer, answer ]
       
[*]如果选A,那么就看answer in [ answer, answer, answer ]是否为假       
[*]如果选B,那么就看answer in [ answer, answer, answer ]是否为假       
[*]如果选C,那么就看answer in [ answer, answer, answer ]是否为假       
[*]如果选D,那么就看answer in [ answer, answer, answer ]是否为假
为了产生一个没有某一项的列表,我们可以将列表中的某一项pop出去,剩下的a3_list。所以:
In :
def test3(answer):
   a3_list=, answer, answer, answer]
   # 先提取出来要检查的项
   refer=a3_list[ answer ]
   # 在把这一项从列表里pop掉
   a3_list.pop( answer )

   # 看看要检查的项是否在剩下的列表中
   return not(refer in a3_list )
In :
print(test3()) # 应当是真
print(test3()) # 应当是假
True False
第4题

以下选项中哪两题的答案相同:
       
[*]A. 第1,5题       
[*]B. 第2,7题       
[*]C. 第1,9题       
[*]D. 第6,10题
这道题其实和第2题的思路一样,建立一个映射关系的字典,
a4_dict={0:,
             1:,
             2:,
             3:}
然后验证题目中所说的东西即可。
       
[*]如果选A,那么看a4_dict中的两项,
               
[*]其中1是a4_dict这个列表的第0项,第1题的答案就是answer[ a4_dict ],               
[*]其中5是a4_dict这个列表的第1项,第5题的答案就是answer[ a4_dict ]       
               
[*]如果选B, 那么看a4_dict中的两项,
               
[*]其中2是a4_dict这个列表的第0项,第2题的答案就是answer[ a4_dict ],               
[*]其中7是a4_dict这个列表的第1项,第7题的答案就是answer[ a4_dict ]       
       
In :
def test4(answer):
   a4_dict={0:,
                  1:,
                  2:,
                  3:}
   return answer[ a4_dict[ answer ]] == answer[ a4_dict[ answer ]]
In :
print( test4() ) # 应当为假
print( test4() ) # 应当为真
False True
第5题

以下选项中哪一题的答案与本题相同
       
[*]A. 第8题       
[*]B. 第4题       
[*]C. 第9题       
[*]D. 第7题
想必已经越来越熟练了,先建立一个映射关系字典:
a5_dict={0:8,
             1:4,
             2:9,
             3:7}
本题的答案当然就是answer,
       
[*]如果选A,那么就是看第8题的答案,也就是answer[ a5_dict ]       
[*]如果选B,那么就是看第4题的答案,也就是answer[ a5_dict ]
In :
def test5(answer):
   a5_dict={0:8,
                  1:4,
                  2:9,
                  3:7}
   return answer == answer[ a5_dict[ answer ] ]
In :
print(test5()) # 应当为真, 第5题的答案与第8题都是A print(test5()) # 应当为假, 第5题的答案选的是B, 但与第4题的答案不同
True False
第6题

以下选项中哪两题的答案与第8题相同
       
[*]A. 第题       
[*]B. 第题       
[*]C. 第题       
[*]D. 第题
出题人已经开始重复自己了,这道题和第4题区别不大。
建立一个映射字典:
a6_dict={0:,
             1:,
             2:,
             3:}
第8题的答案当然是answer,
       
[*]如果选A,那么answer应当等于a6_dict中的第2、4题的答案,
               
[*]其中2是a6_dict,第2题的答案也就是answer]               
[*]其中4是a6_dict,第4题的答案也就是answer]       
       
In :
def test6(answer):
   a6_dict={0:,
                  1:,
                  2:,
                  3:}
   return (answer == answer ]] == answer ]] )
In :
print(test6()) # 应当为真,第6题选了A,第8题的答案是A,第2、4题也选的是A print(test6()) # 应当为假,第6题选了B,第8题的答案是C,第1、6题选的不是C
True False
第7题

此十道题中,被选中次数最少的选项字母为:
       
[*]A. C       
[*]B. B       
[*]C. A       
[*]D. D
先建立个映射字典:
a7_dict={0:2,
             1:1,
             2:0,
             3:3}
这道题开始有新花样了,“选中次数最少的字母”,那就要统计一下每个字母都被选中了多少次。
列表里有个.count(value)方法,可以统计出value在列表中出现了多少次。所以:
       
[*]字母A在答案中出现的次数=answer.count(0)       
[*]字母B在答案中出现的次数=answer.count(1)       
[*]字母C在答案中出现的次数=answer.count(2)       
[*]字母D在答案中出现的次数=answer.count(3)
最少,可以用min(列表)来表示,那么各个字母出现次数中最少的数量就是:
min( )
In :
def test7(answer):
   a7_dict={0:2,
                  1:1,
                  2:0,
                  3:3}
   return answer.count(a7_dict]) == min( )
In :
print(test7(["",1,2,3,4,5,6,0,8,9,10])) # 应当为真,这里面所有的字母都只出现了1次 print(test7(["",1,2,3,4,5,6,1,8,9,10])) # 应当为假,1出现了两次,比其他都多
True False
第8题

以下选项中,哪一题的答案与第1题的答案在字母中不相邻:
       
[*]A. 第7题       
[*]B. 第5题       
[*]C. 第2题       
[*]D. 第10题
先建个映射关系:
a8_dict={0:7,
             1:5,
             2:2,
             3:10}
这道题说的是字母不相邻,我们已经用数字0123表示字母ABCD了,那么相邻,就是相差为±1,或者是减完以后平方=1。Python用**表示平方, 用!=来表示不等于
第一题的答案是answer,
       
[*]如果选A,那么有(answer-answer)**2 !=1       
[*]如果选B,那么有(answer-answer)**2 !=1
In :
def test8(answer):
   a8_dict={0:7,
                  1:5,
                  2:2,
                  3:10}
   return (answer-answer[ a8_dict] ])**2 !=1
In :
print(test8()) #应当为真,第8题选了A,第1题的答案是1,与第7题的答案7不相邻 print(test8()) #应当为假,第8题选了B,第1题的答案是4,与第5题的答案5相邻
True False
第9题

已知“第1题与第6题的答案相同”与“第x题与第5题的答案相同”的真假性相反,那么X为:
       
[*]A. 第6题       
[*]B. 第10题       
[*]C. 第2题       
[*]D. 第9题
建立映射关系:
a9_dict={0:6,
             1:10,
             2:2,
             3:9}
“第1题与第6题的答案相同”,这句话的逻辑值是answer==answer
真假性相反用not表示
       
[*]如果选A,那么X=6,第6题与第5题的答案相同的逻辑值是answer==answer,那么not(answer==answer)==(answer==answer)       
[*]如果选B,那么X=10,第10题与第5题的答案相同的逻辑值是answer==answer,那么not(answer==answer)==(answer==answer)
In :
def test9(answer):
   a9_dict={0:6,
                  1:10,
                  2:2,
                  3:9}
   return not(answer]]==answer)==(answer==answer)
In :
print(test9()) # 应当为假,第9题选了A,第1题与第6题不同,那么第6题应该和第5题相同才是真假性相反, 这里不满足
print(test9()) # 应当为真,第9题选了A,第1题与第6题不同,那么第6题应该和第5题相同才是真假性相反
False True
第10题

在此10道题中,ABCD四个字母出现此处最多与最少者的差为:
       
[*]A.3       
[*]B.2       
[*]C.4       
[*]D.1
我们已经胜利在望,发现出题人也没有太多花招了。这题和前面第7题很相似,只是第7题计算了最少,这里要计算最多了.
既然最少可以用min(列表)来表示,那么各个字母出现次数中最少的数量为: min( )
最多当然用max(列表)来表示,于是各个字母出现次数中最多的数量为: max( )
建立映射关系:
a10_dict={0:3,
               1:2,
               2:4,
               3:1}
In :
def test10(answer):
   a10_dict={0:3,
                  1:2,
                  2:4,
                  3:1}
   answer_count_list=
   diff= max( answer_count_list ) - min( answer_count_list )
   return a10_dict]==diff
In :
print(test10(["",1,2,3,4,5,6,7,8,9,0])) #应当为假,第10题选了A,最大最小要相差3,但每个字母只出现了一次, 最大最小相差是0
print(test10(["",1,1,1,4,5,6,7,8,9,0])) #应当为真,第10题选了A,最大最小要相差3,选1出现了3次,选2、3都没有,最大最小相差是3
False True
穷举

现在已经把上面10道题的判定函数都写好了。要求解的答案,就是要令上述10道题的判别函数都返回为真。
10道单选题,每道题可能有4种答案,一共的可能性是
410=1048576
看起来也不大,所以就穷举好了。最简单的方式就是for循环。虽然也还有其他生成穷举序列的方法,但本着“想到解法就先实现出来看看”的敏捷开发思路,先用for循环吧。
所谓for循环,就是让一个变量依次取得列表中的所有值
In :
choice=
test1=True
answer=[]
for a1 in choice:
   for a2 in choice:
          for a3 in choice:
               for a4 in choice:
                  for a5 in choice:
                         for a6 in choice:
                              for a7 in choice:
                                 for a8 in choice:
                                        for a9 in choice:
                                             for a10 in choice:
                                                answer=["",a1,a2,a3,a4,a5,a6,a7,a8,a9,a10]
                                                if (True==
                                                      test1==
                                                      test2(answer)==
                                                      test3(answer)==
                                                      test4(answer)==
                                                      test5(answer)==
                                                      test6(answer)==
                                                      test7(answer)==
                                                      test8(answer)==
                                                      test9(answer)==
                                                      test10(answer)):
                                                      print(answer)
print("That's all")
['', 1, 2, 0, 2, 0, 2, 3, 0, 1, 0]
That's all
转载自金色葡萄个人主页,已获得授权。(编辑:Steed)

零点黑客 发表于 2021-2-13 23:11:52

人工解题思路:以第九题作突破点,设情况1为真,前真后假。。。。。。设情况2为真,前假后真。。。。。。其实答案很好推

jjw0160 发表于 2021-2-13 23:16:52

这排版,是mathematica终端和python代码的混排么

布川内酷 发表于 2021-2-13 23:21:52

尼玛看了半天,结果是个穷举。(╯‵□′)╯︵┻━┻用个有点技术含量的嘛,递归怎么样。

股神黄老大 发表于 2021-2-13 23:26:52

这排版,是mathematica终端和python代码的混排么

弥敦道奢爷 发表于 2021-2-13 23:31:52

人工解题思路:以第九题作突破点,设情况1为真,前真后假。。。。。。设情况2为真,前假后真。。。。。。其实答案很好推

酷威犬业 发表于 2021-2-13 23:36:52

解:设题9前真后假→1=6 (6 10 2 9 )中三个=5由于2无法=5→9=c,5=c=6 10 9由6=c→1=c 2=a如果前面的都为真,那么4答案不止一个所以9不是前真后假宗上总推导得出 题9前假后真再解:由题9前假后真得出→1不等于6, 6 10 2 9中只有一个等于5由于2不可能等于5, 9不可能等于5所以得出6 10其中一个等于5即是6不等于10 题4答案不可能为d上班中,下班待续

coffeeff 发表于 2021-2-13 23:41:52

结论一 5不等于9结论二 1不等于6结论三 2等于6然后就都出来了都是反证不成立乍一看9显眼,但其实第5、6、9题一起看最快得出结论一

sky棒棒哒 发表于 2021-2-13 23:46:52

你的结论1其实还是需要建立在判断了9真假性这基础。除了9其他都是确定的已知条件题9前真后假直接推导5=9=c(虽然后段推导会证明这方向不成立)光从5 6 9无法推进真假性相反意思是存在2种情况呢

realxle 发表于 2021-2-13 23:51:52

嗯嗯,殊途同归。我的意思是因为5、6、9显眼,所以如果假设5=9=C,则2=A,那么9的真假也就知道了,我是感觉快一点,本质当然都一样啦
页: [1] 2
查看完整版本: 2018年刑侦推理试题解答