求小于等于N的所有正整数里面包含的1的个数

题目:
已知一个正整数N,求比N小(包括N)的所有正整数中包含的1的个数。例如N = 12,则包含5个1,分别为1、10、11、12
解答:
最直观最简单的想法是,从1到N对每一个数检查,得出每个数中包含的一的个数,事件复杂度大概是O(N)
1时间复杂度比较高,不是最优算法。一个比1快的算法是:对N的每一位进行检查,得出比N小的正数某一位包含的1的个数总和。比如1234,千位包含234 + 1个1(1000 ~ 1234),百位包含 2 * 100个1(1100 ~ 1199, 100 ~ 199),十位包含13 * 10个1(1210 ~ 1219,1110 ~ 1119,。。。。。。,10 ~ 19),个位包含124 * 1个1(1231,1221,1211,1201,。。。。。。,1)。按照这个思路可以写出代码如下。
代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;

int getNumAfterI(char *buf, int i, int len)
{
	int sum = 0;
	for(int j = i + 1; j < len; j++)
		sum = sum * 10 + (buf[j] - '0');
	return sum + 1;
}

int NumOf1AfterN(int n)
{
	int sum = 0;
	int num = 0;
	char buf[20];
	sprintf(buf, "%d", n);
	int len = strlen(buf);

	for(int i = 0; i < len; i++)
	{
		if(buf[i] > '1')
			sum += (num + 1) * pow(10, len - i - 1);
		else if(buf[i] == '0')
			sum += num * pow(10, len - i - 1);
		else
			sum += (num + 1) * getNumAfterI(buf, i, len);
		num = num * 10 + (buf[i] - '0');
	}
	return sum;
}

//test
int main()
{
	int num;
	while(1)
	{
		cin >> num;
		cout << NumOf1AfterN(num) << endl;
	}

	return 0;
}

 

posted on 2013-05-29 23:35  _Clarence  阅读(445)  评论(0编辑  收藏  举报

导航