華為筆試題:寫乙個程式, 要求功能:求出用1,2,5這三個數不同個數組合的和為100的組合個數。如:100個1是乙個組合,5個1加19個5是乙個組合。。。。
答案:最容易想到的演算法是:
設x是1的個數,y是2的個數,z是5的個數,number是組合數
x+2*y+5*z = 100 求這個方程解的個數number
注意到0<=x<=100,0<=y<=50,0<=z=20,所以可以程式設計為:
number=0;
for (x=0; x<=100; x++)
for (y=0; y<=50; y++)
for (z=0; z<=20; z++)
if ((x+2*y+5*z)==100)
number++;
cout《最容易想到的是上述三重迴圈,迴圈100*50*20次,最低效的演算法
事實上,這個題目是一道明顯的數學問題,而不是單純的程式設計問題。我的解法如下:
因為x+2y+5z=100
所以x+2y=100-5z,且z<=20 x<=100 y<=50
所以(x+2y)<=100,且(x+5z)是偶數
對z作迴圈(因為z的範圍最小,迴圈優化問題,最外層迴圈次數要小,避免過多流水斷裂),求x的可能值如下(x的取值種數就代表了最終解的個數,對於某個z,x定了後y自動確定):
z=0, x=100, 98, 96, ... 0
z=1, x=95, 93, ..., 1
z=2, x=90, 88, ..., 0
z=3, x=85, 83, ..., 1
z=4, x=80, 78, ..., 0
z=19, x=5, 3, 1
z=20, x=0
因此,組合總數為100以內的偶數+95以內的奇數+90以內的偶數+...+5以內的奇數+1,
即為:(51+48)+(46+43)+(41+38)+(36+33)+(31+28)+(26+23)+(21+18)+(16+13)+(11+8)+(6+3)+1
某個偶數m以內的偶數個數(包括0)可以表示為m/2+1=(m+2)/2
某個奇數m以內的奇數個數也可以表示為(m+2)/2
所以,求總的組合次數可以程式設計為:
number=0;
for (int m=0;m<=100;m+=5)
number+=(m+2)/2;
cout《這個程式,只需要迴圈21次, 兩個變數,就可以得到答案,比上面的那個程式高效了許多倍----只是因為作了一些簡單的數學分析
這再一次證明了:電腦程式=資料結構+演算法,而且演算法是程式的靈魂,對任何工程問題,當用軟體來實現時,必須選取滿足當前的資源限制,使用者需求限制,開發時間限制等種種限制條件下的最優演算法。而絕不能一拿到手,就立刻用最容易想到的演算法編出乙個程式了事——這不是乙個專業的研發人員的行為。
那麼,那種最容易想到的演算法就完全沒有用嗎?不,這種演算法正好可以用來驗證新演算法的正確性,在除錯階段,這非常有用。在除錯階段,對一些重要的需要好的演算法來實現的程式,而這種好的演算法又比較複雜時,同時用容易想到的演算法來驗證這段程式,如果兩種演算法得出的結果不一致(而最容易想到的演算法保證是正確的),那麼說明優化的演算法出了問題,需要修改。
可以舉例表示為:
#ifdef debug // 發布版本將自動取消******的編譯,條件編譯,減少**空間
int ******();
#end if
int optimize();
in a function:
result=optimize();
assert(result==******()); // assert巨集只在debug版本有效,release版本其定義為空
這樣在除錯階段,如果簡單演算法和優化演算法的結果不一致,就會打出斷言。同時,在程式的發布版本,卻不會包含笨重的******()函式。任何大型工程軟體都需要預先設計良好的除錯手段,而這裡提到的就是一種有用的方法。
典型的類似除錯手段是linux核心模組中列印資訊的顯示,通過全域性的顯示級別來控制7類訊息的列印
利用動態規劃的思想求最優解
源自 劍指offer 中的剪繩子問題,書中使用的是c 但是我更喜歡用python實現。這裡按照從上而下的順序計算,也就是說我們先得到f 2 f 3 再得到f 4 f 5 直到得到f n for i in range 4,length 1 max length 0 temp i 2 1 for j i...
如何利用幾何畫板輔助數學教學
幾何畫板軟體提供充分的手段幫助使用者實現其教學思想,只需要熟悉軟體的簡單的使用技巧即可自行設計和編寫應用範例,範例所體現的並不是編者的計算機軟體技術水平,而是教學思想和教學水平,可以說幾何畫板是最出色的教學軟體之一。那麼如何利用幾何畫板輔助數學教學呢?1.借助幾何畫板,體現數學美,激發學生學習數學的...
python 利用虛數解一元方程組
最近在寫乙個產生資料的指令碼,該指令碼可以設定表字段間的邏輯關係。比如 table1.col1 table2.col2 table3.col3。如果設定了這種邏輯關係,那麼勢必會遇到知道其中兩個欄位的值,需要計算第三個字段值的情況。一開始,沒有往深入想,覺得不會很難,就傻乎乎的在寫了。越寫越覺得不好...