程式設計之美 2 4 「1」的數目及擴充套件問題

2021-08-01 21:16:00 字數 1665 閱讀 3362

問題描述:

給定乙個十進位制整數n,求出從1到n的所有整數中出現」1」的個數。

例如:n=2,1,2出現了1個「1」。

n=12,1,2,3,4,5,6,7,8,9,10,11,12。出現了5個「1」。

解題思路:

1.計算

從1到n經歷

的每個數中1的個數相加

其中數字i(1=

#include using namespace std;

typedef unsigned long long int mm;

mm numberof1(mm n)

i=j;

} return num;

}

此程式時間複雜度:

程式設計之美書上寫的是: 

此程式很簡單,需注意:求i各個位上數的過程中會破壞i,故要在求之前儲存好i,在判別完後恢復i。

2.使用列舉法尋找規律,進行數學歸納,用**表示  

歸納過程不再贅述,程式設計之美書上有,這裡更正書裡的乙個錯誤:135頁倒數第二段最後一句,114應改為14,123+1改為13+1。

歸納規律為:

十進位制表示第i為出現1的次數與第i位上的數字有關

,設第i位上的數為p,i位以上的數字為高位數字,

以下的數字為低位數字,如1700030,對於第三位來說,高位數字為1700,低位數字為30,則p滿足以下規則:

p=0    高位數字*(10^(i-1))

p=1     高位數字*(10^(i-1))+低位數字+1

p=2   (高位數字+1)*(10^(i-1))

程式如下:

mm quicknumof1(mm n)

factor*=10;

} return num;

}

程式中注意:

1.要準確的求取低位數字、當前位數字、高位數字;

2.每個case之後要break,降低時間複雜度

3.記得factor要累乘,從而target不同位

此程式的時間複雜度為n的十進位制位數,即

改進:

對於上述分類歸納,可以進一步歸納,可以看出,無論p為幾,該位「1」的個數均包括高位數字*(10^(i-1)),p不同時附加的值不同。p為0或1,附加的值是(低位數字+1)*p;p為其他,附加的值是10^(i-1)。

在程式中,只需要定義變數addnum,利用條件表示式,addnum=p>1?10^(i-1):(

低位數字+1)*p;從而避免了繁瑣的switch語句。

擴充套件問題:

給定乙個十進位制整數n,求出從1到n的所有整數二進位制表達中出現」1」的個數。

對於這個問題,我們同樣列舉二進位制表達每一位上出現「1」的次數,總結歸納,可得:

第i位上「1」出現的次數=高位*(2^(i-1))+第i位數字+低位數字

程式為:

mm quicknumofbinary1(int n)

return num;

}

此程式的時間複雜度為n的二進位制位數,即

程式設計之美2 4 1的數目

總體思路 先求個位上出現的1的個數,再找十位再找百位。先看個位找找規律 5 05 1 1 15 2 1,11 25 3 1,11,21 35 4 1,11,21,31 325 33 1,11,21,31,41,301,311,321 結論 個位上的1的數目s n 10 1 再看十位,找找規律 25 ...

程式設計之美 2 4 「1的數目」

擴充套件問題 二進位制數n,從1開始,到n的所有二進位制數,然後數下其中出現的所有 1 的個數。例如 f 1 1 f 10 2 因為01,10共有2個1 f 11 100 因為01,10,11共有4個1 思路 以10110為例,考慮最高位為0時共有幾個1,因為後面4位中1和0出現的概率是相等的,也即...

程式設計之美 2 4 1的數目

package code.beauty.fungame public class countone private static int count1inaint int n return num private static void count1inallint int n system.out...