找一问题

一.问题

给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。
要求:
写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数。例如 f(12)  = 5。

二.思路:

通过对四位数的例子来分析,不断发现其中的规律,把数分解成各个位数,分开讨论,最后求和。最大的位数需要对是否为1来做判断,若是1(1690),则千位为1的有690个,反之(2563)有1000个。十位和百位规律一样,分别对0,1,大于1三方面入手。若是0(1503),则十位位上的1的个数为150个;若是1(1516),则十位上的1的个数为157个;若是大于1(1556),则十位上的1的个数为160个;个位上则分为是否为0;若是0(1690),则十位位上的1的个数为169个;若不是0(1693),则十位位上的1的个数为170个;最后求和。

三.代码

#include<iostream>
#include<cmath>
using namespace std;
int number(int y,int sum)
{
int x, a[100],b, i = 0,n;
x = y;
while (x >= 10)
{
a[i] = x % 10;
x = x / 10;
i = i + 1;
}
a[i] = x;
for (n = 0; n <= i; n++)
{
cout << a[n] << " ";
}
cout << endl;
b = (int)pow(10, i);
if (a[i] == 1) { sum = y %b + 1; }//最高位的
else { sum = b; }


for (n = i - 1; n > 0; n--)
{
if ((a[n] >1)) sum = sum + (y / ((int)pow(10, n + 1)) + 1) * ((int)pow(10, n));
if ((a[n] == 1)) sum = sum + (y / ((int)pow(10, n + 1))) * ((int)pow(10, n)) + y % (int)pow(10, n) + 1;
if ((a[n] < 1)) sum = sum + ((y / ((int)pow(10, n + 1))) * 10) * ((int)pow(10, n - 1));
}

if (a[0] == 0) sum = sum + y/10;
if (a[0] != 0) sum = sum + y/10 + 1;
return sum;

}
void main()
{
int y, n = 0, sum = 0, m;
cout << "输入一个正整数;" << endl;//分离各个位数
cin >> y;
m = number(y, sum);
cout << "1的个数为:" << m;


}

四.截图

五.总结

这道题需要认真总结发现其中的规律,理清思路,才能写好程序。

posted @ 2015-06-03 16:01  乱——清——无  阅读(128)  评论(0编辑  收藏  举报