编程之美读书笔记(3) 统计在从1到n的正整数中1出现的次数
问题:
给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数。
例如:N= 2,写下1,2。这样只出现了1个“1”。
N= 12,我们会写下1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12。这样,1的个数是5。
问题一:
写一个函数f(N),返回1到N之间出现1的个数,比如f(12)= 5。
解法一:
让我们首先想到的一个方法是:遍历1~N,统计每个数1出现的个数,相加便得到所有1的个数。
<3>3位数情况
同理分析4位数,5位数。。。。。
设N = abcde ,其中abcde分别为十进制中各位上的数字。
如果要计算百位上1出现的次数,它要受到3方面的影响:百位上的数字,百位一下(低位)上的数字,百位一上(高位)上的数字。
如果百位上数字为0,百位上可能出现1的次数由更高位决定。比如:12013,则可以知道百位出现1的情况可能是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。可以看出是由更高位数字(12)决定,并且等于更高位数字(12)乘以 当前位数(100)。
如果百位上数字为1,百位上可能出现1的次数不仅受更高位影响还受低位影响。比如:12113,则可以知道百位受高位影响出现的情况是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。和上面情况一样,并且等于更高位数字(12)乘以 当前位数(100)。但同时它还受低位影响,百位出现1的情况是:12100~12113,一共114个,等于低位数字(113)+1。
如果百位上数字大于1(2~9),则百位上出现1的情况仅由更高位决定,比如12213,则百位出现1的情况是:100~199,1100~1199,2100~2199,...........,11100~11199,12100~12199,一共有1300个,并且等于更高位数字+1(12+1)乘以当前位数(100)。
#include<stdio.h>long long int Count(long long int n){//1的个数long long int count = 0;//当前位long long int Factor = 1;//低位数字long long int LowerNum = 0;//当前位数字long long int CurrNum = 0;//高位数字long long int HigherNum = 0;if(n <= 0){return 0;}while(n / Factor != 0){//低位数字LowerNum = n - (n / Factor) * Factor;//当前位数字CurrNum = (n / Factor) % 10;//高位数字HigherNum = n / (Factor * 10);//如果为0,出现1的次数由高位决定if(CurrNum == 0){//等于高位数字 * 当前位数count += HigherNum * Factor;}//如果为1,出现1的次数由高位和低位决定else if(CurrNum == 1){//高位数字 * 当前位数 + 低位数字 + 1count += HigherNum * Factor + LowerNum + 1;}//如果大于1,出现1的次数由高位决定else{//(高位数字+1)* 当前位数count += (HigherNum + 1) * Factor;}//前移一位Factor *= 10;}return count;}int main(){long long int a;while(scanf("%lld",&a) != EOF){printf("%lld\n",Count(a));}return 0;}
- 1楼SJF0115前天 12:54
- [code=cpp]n#include<stdio.h>nint main(){n return 0;n}n[/code]
