分治演算法 統計數字問題

2021-10-14 15:48:01 字數 2480 閱讀 2780

參考文章:

1-1統計數字問題(詳解)

步驟一:

先求鍵盤輸入的數n是乙個幾位數,設位數為len

公式log(n)+1;

可用cmath裡的函式:double log10(double x)來求解

步驟二:

劃分區間,然後相加

把數n盡可能的劃分為較少的區間。【按位數劃分】

223,可劃分成00-99,100到199(兩個區間)

3333,可劃分為000-999,1000到1999,2000到2999(三個區間)

後兩個區間比第乙個區間分別多了1000個1和2,其餘數字相同。

在這每乙個區間內(除了最高位)0-9出現的次數是**(len-1)*10^(len-2)**----(列舉一下可發現規律)

現在我們知道了每個區間的0-9出現的次數,該求區間數了:

如233區間數就是2,3333的區間數就是3,所以數n的區間數p是n/(10^(len-1))

綜上,如3333,從000-2999(除了最高位)0到9的每個數的個數為p(len-1)10^(len-2)

以3333為例,上面的那個公式都沒有計算千位數出現的次數,而是把劃分好的區間計算完了,3333分為三個區間,區間數3乘以0-9出現的次數,其實就是計算了三次000-999出現的次數。

步驟三:

最高位相加

如3333,上一步我們已經算好從000到2999,(除了最高位)0到9每個數的和了

現在來算最高位

最高位(第4位)的數有0、1、2、3

0:0000-0999共1000個

1:1000-1999共1000個

2:2000-2999共1000個

3:3000-3333共333+1個

設最高位為m可得**如下

for

(int i=

0;i)c[m]+=

1+n%((

int)

pow(

10.0

,len-1)

);

步驟四:

遞迴處理完3333的000-2999個數以及3作為第len位的情況剩下333遞迴處理333

即要處理t=n%(10^(len-1))

注意:(1)若t為0,比如200,此時c[0]要加len-1也就是2!

若數10,則t為0,c[0]要加len-1,也就是1,

然後結束遞迴.

(2)若t不為0,這裡特判一下,若lent!=len-1說明是諸如10010這種情況,中間兩個0還是要處理的,

c[0]+=(len-lent-1)*(t+1)

fill()函式引數:fill(first,last,val);

// first 為容器的首迭代器,last為容器的末迭代器,val為將要替換的值。

注意: fill()中 ,它的原理是把那一塊單元賦成指定的值,也就是說任何值都可以

memset(),則是將s所指向的某一塊記憶體中的每個位元組的內容全部設定為ch指定的ascii值,即0 、1

#include

using

namespace std;

//統計數字問題 遞迴法

int c[10]

;void

solve

(int n)

int lent=

log10

(t)+1;

if(lent!=len-1)

c[p]

+=t+1;

return

solve

(t);

}int

main()

for(

int i=

0; i<

10; i++)}

return0;

}

統計數字問題

在王曉東編著的 演算法設計與實驗題解 中看到的這個問題,問題描述如下 一本書的頁碼從自然數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 ...