比较无聊的一天,小明决议列举了一大堆石头。他先数了数石头,发明堆里有几块石头,然后到市肆去买标签。每一个标签都是从0到9的数字,每一个石头都应该分派一个唯一的数字,从1到N。假如每一个标签的本钱是1美圆,小明会花多少钱在这个项目上?
function rocks(int $n): int {
return ;
}
个中:
$n为石头数,且$n为大于1的正整数
返回为须要的本钱
例子:
小明发明了13块石头:
则石头上的数字为:
1,2,3,4,5,6,7,8,9,10,11,12,13
所须要的标签为:
1,2,3,4,5,6,7,8,9,1,0,1,1,1,2,1,3
所须要的本钱为:
17
这道题关于我们来说,很多人的牢固思绪就是以下这类
function rocks(a) {
var str = '';
for(var i=1; i<=a; i++){
str += i;
}
return str.length;
}
rocks(13);
经由过程求长度的体式格局来处理这类题目,然则假如说数据量一大,就会形成溢出。所以我们要革新一下算法。
以下是我对这道题的明白:
经由过程题意得知,假如是1位数的,就是1张标签,假如是两位数的就是两个标签,假如是三位数的就是三个标签。
我们只须要轮回他所通报的长度的次数就能够了,经由过程,等差数列的体式格局,求出次数,
比方:
1位数: 10-1 * 1
2位数: 1010 – 101 * 2
3位数: 101010 – 10 10 2
以下是我的代码:
function rocks(int $n): int {
// 获得长度.
$length = strlen($n);
$count = 0;
if($length > 1){
// 轮回长度-1次. 这里求的是位数
for($i=1;$i<$length;++$i){
$count += $i * (pow(10,$i)-pow(10,$i-1));
}
// 假如到了 末了一次即到了 10的i次方 直接用n来减去即可
$count += ($n - pow(10,$i-1) + 1)*$i;
return $count;
}else{
return $n;
}
}