找出一个比N大且最接近的数,这个数的每位之和与N相同,用代码实现之。

20 篇文章 0 订阅
<?php

/**
 * 一个K位的数N (K≤2000,N≤1020)
 *找出一个比N大且最接近的数,这个数的每位之和与N相同,用代码实现之。
 *例如:0050 所求书数字为0104;112 所求数为121
 * @param string $s 数字字符串
 * @param bool $type 是否固定位 true:是 false:否 默认:false
 * @return string
 */
 
function findBigNear($s, $type = false){
    $str = $s; // 新字符容器
    $len = strlen($s); // 得到字符位数
    $sum = 0; // 得到所有位之和
    $a = 0; // 变化位位置
    $c = true; // 记录倒序首位不为零
    $d = true; // 无解
 
    // 得到应该变化的位置及数值 判断无解 得到总和 102
    for ($i=$len-1;$i>-1;--$i) {
        $sum += $str[$i]; // 求和
 
        if ($c) {
            if ($str[$i]) $c = false;
        } else {
            if ($str[$i] != 9) {
                $a = $i;
                $d = false;
                break;
            }
        }
    }
	
	// 是否固定位 true:是 false:否
	if ($d) {
		if ($type) { // 固定位
			return '无解'; // 判断无解
		
		} else { // 位数不固定
			
			$str[0] = 1;
	        $sum -= 1;
			
	        for ($i=$len;$i>0;--$i) {
	            if ($sum > 9) {
	                $str[$i] = 9;
	            
	            } else {
	                $str[$i] = $sum;
	            }
	            $sum -= $str[$i];
	        
	        }
	        return $str;
		}
	}
	
    // 填入数字
    for ($i=0;$i<=$a;++$i) {
        if ($i == $a) {
            $str[$i] = $s[$i]+1;
            $sum -= $str[$i];
        } else {
            $str[$i] = $s[$i];
        }
    }
 
    for ($i=$len-1;$i>$a;--$i) {
        if ($sum > 9) {
            $str[$i] = 9;
        } else {
            $str[$i] = $sum;
        }
        $sum -= $str[$i];
    }
 
    return $str;
}

echo '固定位测试<br/>';
echo findBigNear('9', true),'<br/>';
echo findBigNear('10', true),'<br/>';
echo findBigNear('11', true),'<br/>';

echo '<br/>非固定位测试<br/>';
echo findBigNear('9'),'<br/>';
echo findBigNear('10'),'<br/>';
echo findBigNear('11'),'<br/>';

运行结果如下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值