參考文章:
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 ...