热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

每日一题:一石头这里注重算法和效率

比较无聊的一天,小明决定列举了一大堆石头。他先数了数石头,发现堆里有几块石头,然后到商店去买标签。每一个标签都是从0到9的数字,每一个石头都应该分配一个唯一的数字,从1到N。如果每

比较无聊的一天,小明决定列举了一大堆石头。他先数了数石头,发现堆里有几块石头,然后到商店去买标签。每一个标签都是从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 &#8211; 101 * 2
3位数: 101010 &#8211; 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;
}
}

推荐阅读
author-avatar
月舞B的啊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有