统计1到N之间所有十进制数中数字1的个数。
2013-03-03 19:27
260 查看
这是一道十分有趣的题,例如N为12的时候,输出是5,因为从1到12,总共有1,10,11,12中包含数字1,总共是5个。
最傻逼的办法当让是直接枚举,即N^2的方法,对于小数据,是可以容忍的,但是此题中N最大可以达到2^30次方,因此
该方法不行。
我觉得这一题更偏数学一点,只要找到了递推公式,变成是非常简单的。
我们用part1来表示1-99..99中所包含的1的个数
1-9中有只有1一个
1-99总共有20个
递推公式很容易得到,part1
= part1[n-1]*10 + 10^(n-1),其中N表示9的个数。
对于N,我们从N的个位数开始往高位递推。
如下图所示
![](http://images.cnitblog.com/blog/476530/201302/28163107-5f3c4794e4d64d23ba7b069e67377d09.jpg)
假设我们已经进行到n位,我们用part2表示前n位的结果。N的第n位数字是t,那么前N位的结果
part2
= part2[n-1] + t*part1[n-1]。
如果t = 1,那么还要再加上N mod (10^(n-1))的结果,如果t>1,加上10^(n-1)的值即可。
代码如下:
最傻逼的办法当让是直接枚举,即N^2的方法,对于小数据,是可以容忍的,但是此题中N最大可以达到2^30次方,因此
该方法不行。
我觉得这一题更偏数学一点,只要找到了递推公式,变成是非常简单的。
我们用part1来表示1-99..99中所包含的1的个数
1-9中有只有1一个
1-99总共有20个
递推公式很容易得到,part1
= part1[n-1]*10 + 10^(n-1),其中N表示9的个数。
对于N,我们从N的个位数开始往高位递推。
如下图所示
![](http://images.cnitblog.com/blog/476530/201302/28163107-5f3c4794e4d64d23ba7b069e67377d09.jpg)
假设我们已经进行到n位,我们用part2表示前n位的结果。N的第n位数字是t,那么前N位的结果
part2
= part2[n-1] + t*part1[n-1]。
如果t = 1,那么还要再加上N mod (10^(n-1))的结果,如果t>1,加上10^(n-1)的值即可。
代码如下:
#include<iostream> using namespace std; int main() { unsigned long n; unsigned long part1,part2,ans,yu; unsigned long base = 1; unsigned int tmp; cin >> n; base = 1; //用来表示10的几次方 ans = 0; //用来存储最终的结果 yu = n%10; //用来表示N mod (10^(n-1))的结果,即余数 part1 = 1; //表示part1 if (yu >= 1) ans = 1; part2 = ans; //表示part2 n = n/10; while (n!=0){ tmp = n % 10; base = base*10; ans = tmp*part1 + part2; if(tmp == 1) ans = ans + yu + 1; else if (tmp > 1) ans = ans + base; part1 = part1*10 + base; part2 = ans; n = n/10; yu = tmp*base + yu; } cout << ans<<endl; return 0; }
相关文章推荐
- 统计1到n之间的所有数字中1出现的个数
- 统计所有0到n之间所有含有数字1的数字和
- 统计1到N之间所有数字中1的个数
- 统计1到n之间的所有数字中1出现的个数
- 写一个函数,计算40亿以内的最大的那个f(n)=n的值,函数f的功能是统计0到n之间所有数字1的数字和
- 统计1到n之间的所有数字中1出现的个数
- a、b、c 均是0 到9 之间的数字。abc+bcc=532,求满足条件的所有a、b、c 的值
- 查找介于n1与n2(0<n1<n2<32768)之间所有满足下列条件的整数: (1)该数的十进制表示中有且仅有两个相同的数字位; (2)该数是素数。
- 递归算出两个数字之间所有数字之和.
- java循环练习:手动输入两个数字m和n,运算求出m~n之间所有偶数的和
- 统计各个数字、空白符、及所有其他字符出现的次数
- 编写一个程序统计输入字符串中: 各个数字、空白字符、以及其他所有字符出现的次数
- 41.用c++编写程序:从键盘上任意输20个1-99之间的整数,分别统计其个位数0-9的数字各有多少
- 随机生成 50 个数字,每个数字的范围在 [10, 50] 之间,统计每个数字出现的次数,最后将每个数字和它出现的次数打印出来
- 编写程序输出1到100之间出现数字9的所有数字
- 查找介于n1与n2(0<n1<n2<32768)之间所有满足下列条件的整数: (1)该数的十进制表示中有且仅有两个相同的数字位; (2)该数是素数。
- 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
- 用两个函数来实现求1到某个数字之间所有的素数并输出
- [分析总结:leetcode-Number of Digit One]寻找整数1到n之间所有数字中1出现的次数
- 设a b c均为0到9之间的数字,abc,bcc是两个三位数,且有:abc+bcc=532,求满足条件的所有a,b,c