问题描写叙述

给定一个十进制整数N,求出从1到N的全部整数中出现”1”的个数。

比如:N=2时 1,2出现了1个 “1” 。

N=12时 1,2,3,4,5,6,7,8,9,10,11,12。

出现了5个“1”。

解题思路

1位数的情况:

在解法二中已经分析过,大于等于1的时候。有1个,小于1就没有。

2位数的情况:

N=13,个位数出现的1的次数为2。分别为1和11,十位数出现1的次数为4,分别为10,11,12,13,所以f(N) = 2+4。

N=23,个位数出现的1的次数为3,分别为1,11,21,十位数出现1的次数为10,分别为10~19,f(N)=3+10。

由此我们发现。个位数出现1的次数不仅和个位数有关。和十位数也有关,假设个位数大于等于1,则个位数出现1的次数为十位数的数字加1;假设个位数为0。个位数出现1的次数等于十位数数字。而十位数上出现1的次数也不仅和十位数相关,也和个位数相关:假设十位数字等于1,则十位数上出现1的次数为个位数的数字加1,假如十位数大于1,则十位数上出现1的次数为10。

3位数的情况:

N=123

个位出现1的个数为13:1,11,21,…。91,101,111,121

十位出现1的个数为20:10~19,110~119

百位出现1的个数为24:100~123

我们能够继续分析4位数,5位数,推导出以下普通情况:

实现代码

#include <iostream>
#include <cstring>
using namespace std; int countOne(int n)
{
int current = 0;
int before = 0;
int after = 0;
int i = 1;
int count = 0;
while (n / i != 0)
{
current = n / i % 10;
before = n / (i * 10);
after = n - (n / i) * i;
if (current > 1)
{
count += (before + 1) * i;
}
else if (current == 0)
{
count += before * i;
}
else if (current == 1)
{
count += before * i + after + 1;
} i *= 10;
} return count;
} int main()
{
int n;
while (cin>>n)
{
cout<<countOne(n)<<endl;
} return 0;
}
05-11 14:44