【模拟题】页码统计

题目:牛牛新买了一本算法书,算法书一共有n页,页码从1到n。牛牛于是想了一个算法题目:在这本算法书页码中0~9每个数字分别出现了多少次?

输入描述:  输入包括一个整数n(1 ≤ n ≤ 1,000,000,000)

输出描述:  输出包括一行10个整数,即0~9这些数字在页码中出现的次数,以空格分隔。行末无空格。

例子:

输入 :999      输出:189 300 300 300 300 300 300 300 300 300


思路:

1.容易相待O(N*lgN)时间复杂度的算法,从1到n遍历,找出每个数中,每个数字出现的次数。

2.假设 N=abcde,如果要计算百位上 x 出现的次数,受三个因素影响:百位上的数字,百位以下的数字,百位以上的数字。

   以找 1 的数目为例:

   如果百位数字为0(小于1),百位上出现 1 的次数仅由高位决定,比如 12 013,百位出现 1 的情况为 100 ~199  1 100 ~ 1 199 .... 11 100~11 199,一共等于更高位的数字

                                                 (12)*当前的位数决定。(12*100=1200)。

   如果百位数字为1(等于1),百位上出现 1 的次数为高位和低位共同决定。例如 12 123,受高位影响,有100 ~199  1 100 ~ 1 199 .... 11 100~11 199一共等于更高位的数字

                                                 (12)*当前的位数决定。(12*100=1200)。同时受低位影响,百位出现 1 的情况一共 12 100 ~ 12 113 一共14个,等于低位数(13)+1。

   如果百位数字为 2~9(大于1),百位上出现 1 的次数仅由高位决定,比如 12 213,百位出现 1 的情况为 100 ~199  1 100 ~ 1 199 .... 12 100~12 199,一共等于更高位的字

                                                  加1(12+1)*当前的位数决定。(1300)。


代码:

#include 
#include 
#include 
using namespace std;

int count_xNum(int n, int x){
	int xCount = 0,j,i=1;
	while (j = n / i){
		int higher = j / 10;
		if (x == 0){
			if (higher) higher--; // 排除 00011 这种情况
			else break;
		}
		xCount += higher*i;
		int temp = j % 10;
		if (temp > x)
			xCount += i;
		else if (temp == x)
			xCount += n-j*i + 1;
		i *= 10;
	}
	return xCount;
}

int main()
{
	long long n;
	cin >> n;
	cout << count_xNum(n, 0);
	for (int i = 1; i <= 9; ++i)
		cout << " " << count_xNum(n, i);
	cout << endl;
	return 0;
}




你可能感兴趣的:(【模拟题】页码统计)