昨日偶然发现一个有趣的数学题。
题目:1到9,9个数,组成任意4位数,乘于一个一位数,得到的结果,正好是剩下的4个数,条件:9个数必须都用到,但不能重复。
网上有些代码,但据DYQ的调查,有的要10秒左右才能算出来。用了8重循环。但人家肯定也有些更妙的方法,比如用C写,可能要快很多。
我用IDL搞了一个方法,用了5重循环,充分利用了IDL的数组操作优势。最后速度还是可以的。我的破机器上,也就0.5秒左右。套用QQZ的一句:“VC想要和IDL比速度,都要掂量掂量自己的水平”不过,IDL也不是随便乱写就出效率的。总之所有语言都不错。存在即有理。看怎么用了。
下边是源代码,大家看看能不能把5重循环再减少几个。。。。。
源码:
Function SetDifference, a, b
mina = Min(a, Max=maxa)
minb = Min(b, Max=maxb)
if (minb gt maxa) or (maxb lt mina) then Return, a ;No intersection...
r = Where((Histogram(a, Min=mina, Max=maxa) ne 0) and $
(Histogram(b, Min=mina, Max=maxa) eq 0), count)
if count eq 0 Then RETURN, -1 else Return, r + mina
End
;+-------------------------------------------------------------------------------------------------
Pro test
arr = Lindgen(9) + 1
timelabel = Systime(/sec)
for i=0, 8 do begin
a = arr[i]
for j=0, 8 do begin
aa = arr[j]
if a eq aa then Continue
for k=0, 8 do begin
aaa = arr[k]
if aaa eq a or aaa eq aa then Continue
for m=0, 8 do begin
aaaa = arr[m]
if aaaa eq a or aaaa eq aa or aaaa eq aaa then Continue
na = a * 1000 + aa * 100 + aaa * 10 + aaaa
for n=0, 8 do begin
nb = arr[n]
if nb eq a or nb eq aa or nb eq aaa or nb eq aaaa then Continue
used = [a, aa, aaa, aaaa, nb]
cs = SetDifference(arr, used)
pu = na * nb
parr = [pu/1000, (pu mod 1000) / 100, (pu mod 100) / 10, pu mod 10]
if ARRAY_EQUAL(parr[sort(parr)], cs[sort(cs)]) then $
print, Strtrim(na, 2) + ' * ' + Strtrim(nb, 2) + ' = ', Strtrim(pu, 2)
endfor
endfor
endfor
endfor
endfor
print, '遍历时间: ', Systime(/sec) - timelabel
End