跳石板

#跳石板 小易来到了一条石板路前,每块石板上从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有局限,但希望找到更好的运行方式。 有更有效率的方式的话,希望可以互相讨论。

转载于:https://my.oschina.net/u/3095608/blog/810605

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值