在csdn上面看到的题目

优快云每日一练(day2) 有一只小鱼,它上午游泳150公里,下午游泳100公里,晚上和周末都休息(实行双休日),假设从周x(1<=x<=7)开始算起,请问这样过了n天以后,小鱼一共累计游泳了多少公里呢?输入两个整数x,n(表示从周x算起,经过n天,n在long int范围内)。输出一个整数,表示小鱼累计游泳了多少公里。1、题目名称:小鱼的航程(改进版) 阅读详情
在csdn上面看到一道题目:
对于任意正整数n,f(n)表示从1到n中数字1出现的次数。例如f(3)=1;   f(11)=4;   f(13)=6;
设计一个算法来计算f(n);
最开始想到的算法是最直接的算法:对1到n的每个数字m,将m转换成字符串,计算该字符串中字符‘1’出现的次数。所有的次数的和就是计算的结果。具体算法如下:
 
public long countAppearTimes(long n)
{
long appearTimes = 0;
for (long i = 1; i <= n; i++)
{
   String strN = String.valueOf(i);
   int length = strN.length();
   for (int i=0; i< length; i++)
   {
        if (strN.charAt(i) == ‘1’)
        {
           appearTimes = appearTimes + 1;
        }
   }
}
return appearTimes;
}
这个算法比较直接,也比较好理解,但是效率太低下。当n比较小的时候还显示不出来,但是当n比较大的时候,就十分明显了。在我的机器上,当n=999999999时,运行了540047ms,也就是9分钟的时间。
      是否有比较简单、高效的算法呢?
我们来做一下转换。假设给出的n是一个m位的数字,可以表示为
a1a2a3a4a5a6......am。那么将从1到n的所有的数字都按m位编写,不足的在左端补0。具体形式如下
0         0          0         0      ......     0           0          1
0         0          0         0      ......     0           0          2
......
0         0          0         0      ......     0           1          0
0         0          0         0      ......     0           1          1
......
a1     a2     a3         a4     。。。。。。         am-2         am-1                   am
我们可以发现以下的规律:
个位上的数字,每10个中就有1个1;
十位上的数字,每100个中有10个1;(10——19)
百位上的数字,每1000个中有100个1;(100——199)
依次类推,在从前向后数的第i位上的数字,每10m-i+1个中就有10m-i个1。
因此,对于n= a1a2a3a4a5a6......am;第i位的数字为ai
1.     如果ai 等于0,那么第i位上有 a1a2a3a4a5a6...... ai-1 * 10 m-i 个1。
也就是说,如果ai 等于0,那么第i位上的1的个数为n/10m-i+1*10m-i个1;
注意,/表示整除,例如132/10 = 13。以下相同。
例如:n=13059;第三位为0。那么第三位上的1共有
13059/105-3+1*105-3=1300个。即
100——199,1100——1199,2100——2199,3100——3199,4100——4199,5100——5199,6100——6199,7100——7199,8100——8199,......,13100——13199。
2.     如果ai等于1,那么从1到a1a2a3a4a5a6... ai-1099...9,第i位上的1的个数可以根据情况1计算出来。从a1a2a3a4a5a6... ai-1100...0到a1a2a3a4a5a6... ai-11 ai+1 ai+2... am 中第i位上的1的个数为 ai+1 ai+2... am+1个,即n%10m-i + 1个。(%表示取余,例如132 %10 = 2。以下相同)所以第i位上共有n/10m-i+1*10m-i + n%10m-i + 1个1。
3.     如果ai位是其他的数字,那么第i位上共有n/10m-i+1*10m-i + 10m-i  =(n/10m-i+1+1)* 10m-i个1。具体的推算各位可以自己去验证。
根据这思想,就有以下的算法。
public long countAppearTimes(long n){
        long times = 0;
        String str = String.valueOf(n);
        int length = str.length();
        for (int i=0; i<length; i++){
//注意这里i是从0开始的,上面的算法描述中的是从1开始的,因此以下的程序稍有不同。
            long exp = Math.round(Math.pow(10, length-i-1));
            long mod = n % exp;
            long div = n / exp;
            long tempTimes = 0;
          
            if (str.charAt(i)=='1'){
                tempTimes = mod + 1;
                tempTimes = tempTimes + (div -1) * exp / 10;
                times = times + tempTimes;
            }
            else{
                if (str.charAt(i) == '0')
                    tempTimes = tempTimes + div / 10 * exp;
                else
                    tempTimes = tempTimes + (div /10 +1)*exp;
                times = times + tempTimes;
            }
        }
        return times;
    }
通过验证,这个算法和最原始的算法的结果是完全相同的(验证了从1到99999999)。
这个算法的效率如何呢?当n=999999999时,运行了109ms。
Java50道经典题目 Java 50题 经典题目 训练java基础及思维能力 立即下载

相关推荐

经典编程100题

经典编程100题,c语言练习,坚持打代码才是王道!题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去掉不满足条件的排列

寻找旋转排序数组中的最小值

153. 寻找旋转排序数组中的最小值 难度中等413收藏分享切换为英文接收动态反馈 已知一个长度为n的数组,预先按照升序排列,经由1到n次旋转后,得到输入数组。例如,原数组nums = [0,1,2,4,5,6,7]在变化后可能得到: 若旋转4次,则可以得到[4,5,6,7,0,1,2] 若旋转4次,则可以得到[0,1,2,4,5,6,7] 注意,数组[a[0], a[1], a[2], ..., a[n-1]]旋转一次的结果为数组[a[n-1], a[0],...

a707931675的博客 374

Perplexity SPACE沙箱平台:安全AI开发环境实战解析

沙箱技术通过资源隔离和权限控制创建受限执行环境,其核心原理是容器化隔离机制。在AI开发领域,这种技术解决了环境配置复杂性和安全风险等关键问题。SPACE沙箱平台作为AI代码执行环境,提供了标准化的开发沙箱,支持Python生态和主流AI框架。通过实战案例展示,该平台特别适用于情感分析等NLP任务的快速原型验证,帮助开发者在安全隔离的环境中测试AI模型和算法,显著提升开发效率并降低系统风险。

weixin_29029995的博客 274

优快云每日一练(编程题)

优快云每日一练部分习题汇总

Miss Z的博客 1703

利用易特天下 ipbox&零层壹号 sdwan 组网盒子实现异地组网

一款支持zerotier的异地组网盒子

v808v808的博客 3349

评价模型——层次分析法(AHP)与熵权法(EWM)

层次分析法是定性与定量结合的多准则决策、评价方法。将决策的有关元素分解成目标层、准则层和方案层,并通过人们的判断对决策方案的优劣进行排序,在此基础上进行定性和定量分析。它把人的思维过程层次化、数量化,并用数学为分析、决策、评价、预报和控制提供定量的依据。

好好学习 天天向上 2万+

labuladong刷题笔记五(递归)

C#实现、利用递归。js动态规划

该用户还没想到好的昵称的博客 382

RIGOL DS1102E示波器新手必看:从开机到捕获第一个波形的5分钟指南

本文为RIGOL DS1102E示波器新手提供了一份快速上手指南。内容涵盖从开机、探头校准到捕获第一个波形的完整流程,重点解析了触发设置、自动测量等核心操作,并指出了探头衰减比设置等常见误区,帮助用户快速掌握这款经典数字示波器的基本使用方法。

dream的博客 740

查找典型例题

本篇博客通过三个实际例题展示了查找算法的应用。首先,使用快速排序算法解决了“求第k大的数”问题,通过排序后直接输出第k大的元素。其次,通过冒泡排序和遍历查找,解决了“查找三个数组的最小共同元素”问题,确保找到三个数组中共同的最小元素。最后,利用冒泡排序在“查找循环顺序数组的最小元素”问题中,通过排序后输出数组的最小值。每个问题都提供了详细的代码实现和解释,帮助读者理解算法的具体应用。

小瑾的博客 392

ros2 humble中使用realsense t265与d435

前提,安装realsense SDK 2.51.1版本并且能成功启动realsense-viewer V2.51.1想要在ros2中使用realsense t265,必须配合realsense SDK v2.51.1使用realsense-ros 4.51.1版本,因为新版本realsense ros2不再对t265支持下面记录源码编译安装 realsense-ros 4.51.1版本。

m0_72797388的博客 955

IMU标定中的Allen方差

Allen方差 Allen方差是IMU标定任务中的常用工具。IMU标定可以分为确定性误差和随机误差,确定性误差包括:scale、bias、misalignment。随机误差则主要是高斯白噪声和bias随机游走。Allen方差主要用于标定随机误差。 Allen方差获取 Allen方差的计算方法如下: 保持IMU静止, 采集N个数据点。 将N个点定长分组,常用的交叠式Allen方差如下(n=3): 对于每个子集,计算均值后,计算相邻两组的方差,得到的时间-方差曲线即为Allen方差。 Alle

realjc的博客 5734

在优快云上面分享资源的方法

在优快云上面分享资源 看到很多人想要在优快云上面分享资源,但是还不会分享, 所以本期我就为大家提供一下在优快云上面分享资源的方法。 看了网上的好多方法都不靠谱,所以我经过查度娘总结出了如下的方法和步骤,如下: 文章目录 系列文章目录 前言 一、在优快云上面分享资源 二、使用步骤 1.找到上传资源的url地址,进行上传资源 2.等待平台审核通过 3.再补充一篇优快云的博客提供资源地址 前言 如果想要学习Androidstudio的相关内容,需要为An..

云梦归遥【qq_45834685】 4823

QGis软件 —— 1、Windows10下载安装QGis及插件

QGis —— 1、Windows10下载安装QGis及插件

5160

如何在markdown(csdn)中打出某个字符上面的三角帽子符号

如何在markdown(csdn)中打出某个字符上面的三角帽子符号 f^\widehat{f}f​ 输入: $\widehat{f}$ 输出: f^\widehat{f}f​

小呆苗的博客 1610

反光柱定位算法中的移动机器人姿态计算原理-经典三边定位最小二乘法计算定位-直接法计算定位

(二)计算姿态方式是我们已经通过最小二乘得到了小车在地图中的位置或者是雷达在地图中的位置,又因为我们知道雷达与小车的安装坐标,所以可以求解出一其中一个坐标的知量,通过小车在地图中坐标与雷达在地图中坐标可以得到一条向量,通过计算向量在地图中的角度就能得到姿态了。与最小二乘三边测量法相比,新算法在动态调整、优化过程和鲁棒性方面优势明显,尤其适合动态环境下的机器人定位,而最小二乘三边测量法在动态复杂环境中精度相对较低。(一)与(二)的区别主要是在计算姿态上的算法不同。经典三边定位最小二乘法 (法一)

苏凯的博客 1140

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

如何在优快云上面转载博客全文

前言 第一次在优快云上面转载博客,为了尊重版权,尊重知识,特地学习了一点如何转载博客的知识,现在来“小试牛刀”一下 参考博客原址:https://blog.csdn.net/bolu1234/article/details/51867099 步骤 首先打开要转载的博客页面,鼠标右键会出来一个“检查”选项(本人使用的是Chrome浏览器,其他浏览器应该也是类似),例如: 然后页面下边或者右边会出...

ajkdghfa的博客 243

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

如何去除优快云上面的广告

首先我们来下一个插件! 已经准备好了!!!      密码:n69y 下载之后,在谷歌浏览器的设置里面点击更多工具,然后点击扩展程序,然后直接把刚刚下好的插件拖进去(需要点击开发者模式)。 这样表明成功了,刷新你的csdn页面,你会发现tmd,那些恶心的广告没有了。  ...

wust_cyl的博客 2431

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【优快云竞赛】题目讲解+对想打比赛的朋友的一些学习建议(ACM,蓝桥杯,PAT等)

作为一个常年混迹在ACM,PAT,蓝桥杯比赛中的选手来说,题目并不算太难,不过值得建议的是:题目有很多都是原题,这点对比力扣或者牛客的线上赛并不算好,所以我认为官方大大可以在题目质量上去加强以下。

感谢您的关注! 2009

csdn不错,上面有很多我需要的东西

csdn不错,上面有很多我需要的东西,可是我在百度上有空间了,以后有机会也到这来写点东西,呵呵

yhlllq的专栏 276

优快云 周赛 50 期题目详解

优快云周赛第50期题目及解答

qq_42368762的博客 209

如何屏蔽优快云上面的广告

首先我们来下一个插件!!! 插件下载地址 密码:vyfx 下载之后,在谷歌浏览器的设置里面点击更多工具,然后点击扩展程序,然后直接把刚刚下好的插件拖进去(需要点击开发者模式以及勾上在隐身模式下启用)。 这样表明成功了,刷新你的csdn页面,你会发现那些恶心的广告没有了。 ...

riemann_的博客 1277

优快云周赛第30期题目解析(天然气定单、小艺读书、买苹果、圆桌)

优快云周赛第30,成绩“0”分,天然气定单、小艺读书、买苹果🍎、圆桌。 (本文获得优快云质量评分【xx】) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单…… 地址:https://lqpybook.readthedocs.io/   自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。   

m0_57158496的博客 1625

我在优快云上面的Blog开张了……

我在优快云上面的Blog开张了……我会经常上来写些一些资料的。我也有我的BBS,名字叫“有间论坛”http://202.98.123.167/bbs/index.php目前这个BBS在Google上面的排名是第二位,目标当然是第一位了。

renjunok的专栏 659

csdn上面文章转发

原 优快云上转载文章 2018年02月03日 19:12:18 L小台风 阅读数:860更多 &lt;div class="tags-box space"&gt; &lt;s...

jianghuchuanke的博客 1441

优快云 每日一练及周赛介绍

期待各位小伙伴能将老顾不懂的优快云每日一练题目破解

文盲的专栏 7959
上一篇: Oracle初级培训中学习到的以前忽略了的细节
下一篇: Velocity学习笔记1——Velocity是什么
afrag
博客等级 码龄21年 5粉丝 15原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值