问题描写叙述
给定一个十进制整数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;
}