統計數字問題
演算法實現
(補0遞迴法)
問題描述:
一本書的頁碼從自然數1開始順序編碼直到自然數
n。書的頁碼按照通常的習慣編排,每個頁碼都不含多餘的前導數字
0。例如第6頁用
6表示而不是06或
006。數字統計問題要求對給定書的總頁碼,計算出書的全部頁碼中分別用到多少次數字
0,1,2,3,.....9
。
演算法分析:
這個演算法使用遞迴的方法來實現,具體步驟如下:
具體的演算法思想是:
說明:n為乙個自然數,
m表示為十進位制數的位數(如
1234,則n
為1234,m
為4)。
對於乙個m位整數,我們可以把0到
n之間的
n+1個整數從小到大這樣來排列:
000......0
.............
099......9
100......0
100......1
.............
199......9
200......0
.............
299......9
300......0
.......... n
這樣一直排到自然數n。對於從0到
199......9
這個區間來說,拋去最高位的數字不看,其低
m-1位恰好就是
m-1個0到
m-1個9共
10^(m-1)個數,這時對於此區間共有
(m-1)*10^(m-1)個數字(包括0~
9)。利用原著中的遞推公式,在這個區間裡,每個數字出現的次數(不包括最高位數字)為
(m-1)*10^(m-2)。
假設n的最高位數字是
x,那麼在
n之間上述所說的區間共有
x個。那麼每個數字出現的次數
x倍就可以統計完這些區間。再看最高位數字的情況,顯然0到
x-1這些數字在最高位上再現的次數為
10^(m-1),
因為乙個區間長度為
10^(m-1)。
而x在最高位上出現次數就是
n%10^(m-1)+1了。接下來對
n%10^(m-1)(這個數其實就是去除最高位剩下的位數),
即n去掉最高位後的那個數字再繼續重複上面的方法直到個位,就可以完成題目要求了。
詳細的例子說明:
對於乙個數字
34567
,我們可以這樣來計算從1到
34567
之間所有數字中每個數字出現的次數: 從
0到9999
,這個區間的每個數字的出現次數可以使用原著中給出的遞推公式,即每個數字出現
4000
次。從10000
到19999
,中間除去萬位的
1不算,又是乙個從
0000
到9999
的排列,這樣的話,從0到
34567
之間的這樣的區間共有
3個。所以從
00000
到29999
之間除萬位外每個數字出現次數為
3*4000
次。然後再統計萬位數字,每個區間長度為
10000
,所以0,1,2
在萬位上各出現
10000
次。而3
則出現4567+1=4568
次。之後,拋掉萬位數字,對於
4567
,再使用上面的方法計算,一直計算到個位即可。
#include#include#includeint a[12];
int cj(int n)//求10的n次方
for(i=0; i
統計數字問題
在王曉東編著的 演算法設計與實驗題解 中看到的這個問題,問題描述如下 一本書的頁碼從自然數1開始順序編碼直到自然數n。書的頁碼按照通常的習慣編排,每個頁碼都不含多餘的前導數字0。例如第6頁用6表示而不是06或006。數字統計問題要求對給定書的總頁碼,計算出書的全部頁碼中分別用到多少次數字0,1,2,...
統計數字問題
問題描述如下 一本書的頁碼從自然數1開始順序編碼直到自然數n。書的頁碼按照通常的習慣編排,每個頁碼都不含多餘的前導數字0。例如第6頁用6表示而不是06或006。數字統計問題要求對給定書的總頁碼,計算出書的全部頁碼中分別用到多少次數字0,1,2,3,9。演算法設計與分析習題 分析 考察由0,1,2.9...
統計數字問題
問題描述 給定乙個整數n,統計從1到n 數字最高位不允許為0 這麼多個數中0,1,2,3,4,5,6,7,8,9分別出現的次數。問題解決 採用遞迴求解統計每乙個數字0,1,2,9出現的次數累加。源 include stdafx.h include int results 10 void count ...