一、编程语言
Excel vba,即运行在Excel电子表格环境下的VB脚本语言。
二、编程环境
Excel 2007 或 2010,均可,新建Excel电子表格文件,在表名的位置,单击鼠标右键,选择查看代码,贴入代码,定位在程序代码内,单击运行,可得结果。
注意,后面程序代码中的序号需要去掉,如1.及2.等。
三、程序代码
Private Sub cmdDo_Click()
Application.ScreenUpdating=False
Dim getDote As Double, sAnswer As String
'编程:洛阳宜阳阿甘
k=0
For k1=65 To 68
For k2=65 To 68
For k3=65 To 65
For k4=65 To 68
'For k5=65 To 68 '第5题不加入循环,由第2题得出
For k6=65 To 68
For k7=65 To 68
For k8=65 To 68
For k9=65 To 68
For k10=65 To 68
k=k+1
q=0
a1=Chr(k1)
a2=Chr(k2)
a3=Chr(k3)
a4=Chr(k4)
a5=Switch(a2="A","C",a2="B","D",a2="C","A",a2="D","B") '直接由第2题得出第5题答案
a6=Chr(k6)
a7=Chr(k7)
a8=Chr(k8)
a9=Chr(k9)
a10=Chr(k10)
sAnswer=a1 & a2 & a3 & a4 & a5 & a6 & a7 & a8 & a9 &a10
'根据第3题,做出判断
l=Switch(a3="A", a3 & a6 & a2 & a4,a3="B", a6 & a3 & a2 & a4,a3="C", a2 & a6 & a3 & a4,a3="D", a4 & a6 & a2 & a3)
m=Left(l,1)
n=Right(l,3)
If InStr(1,n,m) Then GoTo nextData
'根据第 4 题进行判断
l=Switch(a4="A", a1 & a5,a4="B",a2 & a7,a4="C",a1 & a9,a4="D",a6&a10)
m=Left(l,1)
n=Right(l,1)
If mn Then GoTo nextData
'根据第 5 题,做出判断
l=Switch(a5="A",a8,a5="B",a4,a5="C",a9,a5="D",a7)
If a5l Then GoTo nextData
'根据第 6 题,做出判断
l=Switch(a6="A",a2 & a4,a6="B",a1 & a6,a6="C",a3 & a10,a6="D",a5 & a9)
m=Left(l,1)
n=Right(l,1)
If mn Or ma8 Then GoTo nextData
'根据第 7、10 题进行判断
Dim nMix As Integer, nMin As Integer
la=nfunCount(sAnswer,"A")
lb=nfunCount(sAnswer,"B")
lc=nfunCount(sAnswer,"C")
ld=nfunCount(sAnswer,"D")
nMax=Application.WorksheetFunction.Max(la,lb,lc,ld)
nMin=Application.WorksheetFunction.Min(la,lb,lc,ld)
l=Switch(a7="A",lc,a7="B",lb,a7="C",la,a7="D",ld)
If lnMin Then GoTo nextData '第 7 题
l=Switch(a10="A",3,a10="B",2,a10="C",4,a10="D",1)
If lnMax-nMin Then GoTo nextData '第 10 题
'根据第 8 题进行判断
l=Switch(a8="A",a7,a8="B",a5,a8="C",a2,a8="D",a10)
If Abs(Asc(l)-Asc(a1))=1 Then GoTo nextData
'根据第 9 题进行判断
l=Switch(a9="A",a6,a9="B",a10,a9="C",a2,a9="D",a9)
If (a1=a6)=(l=a5) Then GoTo nextData
'如果可以通过以上检验,那就是真命天子了
msgBox "答案依次是:" & sAnswer
nextData:
Next
Next
Next
Next
Next
'Next '第5题不加入循环,由第2题得出
Next
Next
Next
Next
End Sub
'上面的程序代码中,需要调用此过程
'此过程的作用为,统计一个字符串中,某个字符出现的次数
Function nfunCount(a As String,b As String)
f=0
For e=1 To Len(a)
If Mid(a,e,1)=b Then f=f+1
Next
nfunCount=f
End Function
四、后记
推理中的数据统计,共10道题,每道题有4个选项,不考虑各题目之间的关系,假设每道题的4种选项都有可能的话,全部10道题的答案,共有4的10次方种可能(即4^10,共100多万种,具体为1048576种可能)
由于第2题和第5题直接相关联,且是一一对应的确定关系,根据其中一题可直接得出另一题的答案,所以程序中,第5题的答案直接根据第2题答案得出,即第5题不参与循环,10道题只用假设9道题即可,那么,全部10道题的答案,变成4的9次方种可能(即4^9,共20多万种,具体为262144种可能)。上述程序从20多万种可能中,筛选出正确答案。正确答案在第10万次判断时出现(具体为第101061次判断)。
每种可能的选项组合,要依次经过从第3题到第10题,共7次判断,判断该组答案组合是否符合题意。任何一题判断通不过,则直接进入下一个循环,不再进行后面的判断。
这种推理方式,属于穷举法,把所有可能的排列组合一个一个列出来,逐个排除,得到最终答案,算是暴力破解吧。网友有用各种编程语言破解的(C语言、Java语言、JavaScript语言、python语言、Node语言),多数为暴力破解,唯有个python程序员,自称用约束库解决问题,不是暴力破解,不懂,不作置评。
用文字推导(见后附链接),只需十数次,用程序穷举,则需判断20多万次,10万次时才判断出来。那么,到底是文字推导好?还是程序穷举好?本想按照文字推导的过程,来编制程序,奈何功力不够,一堆乱麻,没法实现。不知有无高明的算法,使用程序尽量少步骤的推导出结果。
上篇:《2018年刑侦科推理试题》解答(表格函数版)
领取专属 10元无门槛券
私享最新 技术干货