据说是小学数学题 大家有思路没?
昨天吃火锅的时候,有人无意提起,大家拿起手机笔记本再那里算啊算
心里想这个只能程序算吧。。。 看看周围没网吧,就算了。。。
好了,题来了
1-8 组成2个四位数,数字不重复,一个是另一个的4倍。 回复 1# chinafla
看到离上班时间还有10来分钟,没啥事,正好拿这道题来找到一天coding的感觉!
我来先抛个砖头,看看能不能引来宝玉。10分钟的代码当然只考虑方法简单,不管效率高低,反正计算量也非常小,所以就用最烂的办法:枚举
首先这两个四位数,小的数先叫做数A,大的数叫做数B。
先来限定点条件,虽然不限定,多几个循环也能计算,但这样让现码农情何以堪呢!
① 数A的千位上只能为1,假设若不为1,则:
数A最小值为:2134
2134 * 4 = 8536(重复了3,不合要求)
数A的次最小值为:2314
2314 * 4 = 9256(这时已经超过数B可能的最大值8765,也不合要求,别的比2314大的数就更不可能了)
② 数A的个位上只能是 2, 3, 4, 6, 7, 8
因为1上面已经用过了,而5则由于5 * 4 = 20,从而让数B个位上出现了0,不合要求
MsgBox(0, "Result", Main())
Func Main()
Local $iSmallNum, $aMidNum, $sResult = "Num1 Num2" & @CRLF & "--------------------" & @CRLF
Local $aLastNum =
For $n = 0 To UBound($aLastNum) - 1
$aMidNum = StringSplit(StringRegExpReplace("2345678", $aLastNum[$n], ""), "")
For $i = 1 To $aMidNum
For $j = 1 To $aMidNum
If $i = $j Then ContinueLoop
$iSmallNum = Number("1" & $aMidNum[$i] & $aMidNum[$j] & $aLastNum[$n])
$iFlag = CompareString($iSmallNum)
If $iFlag Then $sResult &= $iSmallNum & " " & $iSmallNum * 4 & @CRLF
Next
Next
Next
Return $sResult
EndFunc
Func CompareString($iSmallNum)
Local $aSplit
$aSplit = StringSplit($iSmallNum * 4, "")
For $i = 1 To $aSplit - 1
If $aSplit[$i] == 0 Or $aSplit[$i] == 9 Then Return 0
For $j = $i + 1 To $aSplit
If $aSplit[$i] == $aSplit[$j] Then Return 0
Next
Next
$aSplit = StringSplit($iSmallNum, "")
For $i = 1 To $aSplit
$iFlag = StringInStr($iSmallNum * 4, $aSplit[$i])
If $iFlag Then Return 0
Next
Return 1
EndFunc
据上班已经开始 10分钟了,但是我刚来,cb的新闻不看了,说一下思路。
Python 代码:
import types
from timeit import Timer
def GetX():
for n in range(4444,8888):
b = n%4
if b==0:
a = n>>2
temp = str(a) + str(n)
t = set(temp)
if len(t) == 8 and not( ('0' in t) or ('9' in t) ):
print a , n
exit 本帖最后由 netegg 于 2013-1-8 11:10 编辑
回复 3# MicroBlue
happytc那个思路比较合适,这个重复计算的次数似乎多了,不过不懂python,也许处理过程没有重复计算
#include <Array.au3>
Dim $aArray =
$aNewArray = _ArrayPermute($aArray, "") ;Using Default Parameters
For $i =1 To $aNewArray
If Number(Stringleft($aNewArray[$i], 4))*4 > 8765 Then ExitLoop
If Number(Stringleft($aNewArray[$i], 4))*4 = Number(StringRight($aNewArray[$i], 4)) Then
ConsoleWrite($aNewArray[$i]& @cr)
EndIf
Next
回复 4# netegg
嗯, happytc 那个算法比我的好,效率比我的高。当时我也没多想,只想用 python 写出我的思路。
python 的内建函数太丰富了,一个 set()函数就解决了去重的问题,所以显得比较简洁。 问题这么快就解决了,向算法达人学习 好难哦,看看高手 遇到此题,我越加感受到10进制计数方式的不便。某个外国网站说8进制在未来将会取代10进制,成为人们生活中普遍的计数方式,看来也有道理。 想不到一到小学数学题这么难,代码学习了。 没想太多只需要知道乘数最小数值是1234,最大不超过8765/4即可,速度有点慢,但是也能接受$begin = TimerInit()
$result=""
For $i=1234 To Int(8765/4)
StringRegExp(String($i&$i*4),'(\d).*?\1.*|+',3)
If @error Then $result=$result&String($i)&"----"&String($i*4)&@CRLF
Next
$dif = TimerDiff($begin)
MsgBox(0,$dif,$result)
回复 8# pusofalse
我的代码时间比较固定 但是happytc 的代码时间总是变来变去的有时候比我快点有时候比我慢点
是我自己电脑的原因还是,他代码就是这样的。说实话我没看懂他代码,有点长,变量太多。 回复 11# love5173
应该是你电脑原因了。因为计算量是完全固定的,不会改变的。所以计算时间也会是一样的。
可能是你电脑里的别的程序忽大忽小的占用了资源了。
不会吧,怎么会看不懂?前面我已经说明了呀,最最简单的想法了。 回复 8# pusofalse
这个网站异想天开了
人类的习惯在很多时候是决定性力量。就象现在的键 盘布局一样,明明都知道它效率低。但谁又能把它改过来?因为大家没有感觉不够用,所以根本不会去改它。
我刚刚试了下用二进制做了下这题,由于计算量太小了,看不出它比十进制效率更高。 回复 4# netegg
看了还是蛋哥的方法好理解。 呵呵,和LOVE5173兄思路相同
local $time=TimerInit()
Local $output
local $k=4
For $i=1234 to Int(8765/$k)
$num=$i*$k
If Not StringRegExp($i&$num,'(.)[^\1]*(\1|0|9)',0) Then
$output&=$i&"x4="&$num&@CRLF
EndIf
Next
MsgBox(0,TimerDiff($time),$output)
另一个方法也没有什么新意
local $time=TimerInit()
Local $output
local $k=4
For $i=1234 to Int(8765/$k)
$num=$i*$k
if StringRegExp($num,'0|9',0) Then ContinueLoop
If check($i,$num) Then
$output&=$i&"====>"&$num&@CRLF
EndIf
Next
MsgBox(0,TimerDiff($time),$output)
Func check($data1,$data2)
local $string='12345678'
$a=StringRegExpReplace($string,'['&$data2&']','')
$b=StringRegExpReplace($string,'['&StringRegExpReplace($string,'['&$data1&']','')&']','')
If $a=$b Then Return 1
EndFunc
页:
[1]
2