跳石板
2016-12-23 00:00
274 查看
#跳石板
小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
不知道还有更加有效率的算法方式,本地运行速度0.13秒。
有些LeedingCode网站可能会运行时间过长导致无法成功。
虽然PHP有局限,但希望找到更好的运行方式。
有更有效率的方式的话,希望可以互相讨论。
小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
<?php function JumpDivisor($numA,$numB){ if($numA>$numB||$numA<4){//一些不可跳情况 return -1; } if($numA==$numB){ return 0; } $arr[$numA]=0; for($i=$numA;$i<$numB;$i++){ if(!isset($arr[$i])){ continue; } $addArr=DivisorArray($i); if(!isset($addArr)){ continue; } for($j=0;$j<sizeof($addArr);$j++){ if($i+$addArr[$j]<=$numB){ if(!isset($arr[$i+$addArr[$j]])){ $arr[$i+$addArr[$j]]=$arr[$i]+1; }else{ $arr[$i+$addArr[$j]]=min($arr[$i+$addArr[$j]],$arr[$i]+1); } }else{ break; } } } if(!isset($arr[$numB])){ return -1; }else{ return $arr[$numB]; } } function DivisorArray($num){/*除了1和本身的约束*/ $arr=array(); $arrp=array(); $lenght=sqrt($num); for($i=2;$i<=$lenght;$i++){ $part=$num/$i; if(floatIsInt($part)){ $arr[]=$i; $arrp[]=$part; } } for($i=sizeof($arr)-1;$i>=0;$i--){ $arr[]=$arrp[$i]; } return $arr; } function floatIsInt($num){//可以使用is_int函数代替 if($num-(int)$num==0) return true; return false; } /*返回当前Unix时间戳及微秒数*/ function getCurrentTime () { list ($msec, $sec) = explode(" ", microtime()); return (float)$msec + (float)$sec; } $begin = getCurrentTime(); print_r(JumpDivisor(8,9000)); $end = getCurrentTime(); $spend = $end - $begin; echo "脚本执行时间为:".$spend."\n";
不知道还有更加有效率的算法方式,本地运行速度0.13秒。
有些LeedingCode网站可能会运行时间过长导致无法成功。
虽然PHP有局限,但希望找到更好的运行方式。
有更有效率的方式的话,希望可以互相讨论。