問題描述:
給定乙個十進位制整數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...