1. 程式人生 > >【模擬題】頁碼統計

【模擬題】頁碼統計

題目:牛牛新買了一本演算法書,演算法書一共有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 <vector>
#include <iostream>
#include <cmath>
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;
}