求1到n的所有正整数中1出现的次数
来源:互联网 发布:gpt转mbr数据会丢失吗 编辑:程序博客网 时间:2024/04/30 02:22
分析
设n的位数为L。1到n的所有整数中1的个数由以下(1)(2)两部分构成
(1)长度小于L的所有正整数中的1
包含i个1的数有 C(i, L-1)*9^(L-1-i)个,其中包含0个1的情况中有这个数字是0的情况,不过不影响对1的计数。故长度小于L的所有正整数中1的个数为C(i, L-1)*9^(L-1-i)*i
(2)长度为L且小于n的所有正整数中的1
从最高位开始,将n的每一位计算出来设为 a1, a2, ..., aL, 前n位包含1的个数为count[n]
从前往后处理每一位
sum=0; Loop: A:m位为0,该位置不能改变,继续处理下一位,下一位的计数包含了这种情况 B:m位大于0 B1:m位为1,则令m位为0,后面的位任意取数,1的个数为 sum{i=0~L-m}{C(i, L-m)*9^(L-m-i)*(i+count[m])} B2:m位大于1 B2A:m位取1,一的个数为sum{i=0~L-m}{C(i, L-m)*9^(L-m-i)*(1+i+count[m])} B2B:m位不取1,1的个数为 (am-1)*B1 将对应情况的计数累加到sum上 循环。将(1)(2)两部分的计数相加。
改进
考虑到各位上的循环现象,有更简单的方法
# -*- coding: cp936 -*-import timedef getNumberOfDigits(n): res = 0 base = 10; # 从最低位到最高位,分别计算所有数字在该位上出现1的次数,累加到res上 while(10*n/base != 0): # 当前位每一个完整循环中,1出现的次数 a = n/base # 当前位完整循环的次数 b = base/10 # 加上当前位完整循环中1出现的次数 res += b*a # 计算当前为剩下的没有循环完整的数列中的1的个数 if(n%base >= 2*b): # 虽然没有循环完,但当前循环中所有1已经出现完了 res += b else: # 当前循环只出现了部分1 res += n%base-b+1 base *= 10 return resdef test(n): time1= time.clock() res = getNumberOfDigits(n) time2= time.clock() print n, "\t", res, "\t", (time2-time1)*1000, "ms" # 测试for i in range(1, 30): test(i) test(987654)test(9876543)test(98765432)test(987654321)
输出为
1 1 0.00434199442804 ms2 1 0.00355254089567 ms3 1 0.00315781412948 ms4 1 0.0197363383092 ms5 1 0.00355254089567 ms6 1 0.00986816915463 ms7 1 0.00394726766184 ms8 1 0.00394726766184 ms9 1 0.00355254089568 ms10 2 0.0201310650754 ms11 4 0.00513144796038 ms12 5 0.00473672119422 ms13 6 0.0276308736329 ms14 7 0.0248677862696 ms15 8 0.0055261747266 ms16 9 0.0236836059711 ms17 10 0.004341994428 ms18 11 0.0189468847769 ms19 12 0.025657239802 ms20 12 0.0224994256726 ms21 13 0.0118418029855 ms22 13 0.0244730595035 ms23 13 0.004341994428 ms24 13 0.00473672119417 ms25 13 0.00434199442811 ms26 13 0.004341994428 ms27 13 0.0256572398021 ms28 13 0.00394726766184 ms29 13 0.00473672119428 ms987654 595336 0.0232888792049 ms9876543 6941015 0.00868398885601 ms98765432 79286694 0.0205257918416 ms987654321 891632373 0.0374990427876 ms
- 求1到n的所有正整数中1出现的次数
- 求从1到n的正整数中1出现的次数
- C++求从1到n的正整数中1出现的次数
- 求1到n的正整数中某个字符出现的次数
- 求1到n的正整数中某个字符出现的次数
- 统计从1到n所有正整数中1出现的次数
- 求从1到n的所有数字中,1出现的次数
- 1到n的正整数x出现的次数
- 统计在从1到n的正整数中1出现的次数
- 计算从1到n的正整数中1出现的次数!
- 统计在从1到n的正整数中1出现的次数
- 统计从1到n的正整数中1出现的次数...
- 统计在从1到n的正整数中1出现的次数
- 统计在从1到n的正整数中1出现的次数
- 统计在从1到n的正整数中1出现的次数详解
- 面试题32:从1到n的正整数中1出现的次数
- Uva1225 求数字0-9在前n个正整数中出现的次数(1<=n<=10000)
- 2013年大众点评网笔试题,输入任意正整数n,统计1到n中1出现的次数
- 安卓手机/电脑剪贴板同步工具
- Defensive programming
- 提高班第一次实训——拆装机
- Android 解析XML文件 (SAX与PULL)
- JUnit基础入门
- 求1到n的所有正整数中1出现的次数
- ASP 枟 --Sachiel【笔记】
- C++的五种内存存储区
- 互芯平台短信发送实现
- 记一次线上分布式redis服务BUG发现与修复过程
- PIMPL
- hdu 1331 Function Run Fun
- Linux设备模型之tty驱动架构分析
- iphone之调用系统提示音教程