最近在看《程式設計之美》,為找工作面試做準備。該書中2.20程式理解和時間分析一題沒有給出解答,所以簡單寫一下我自己的答案。
題目如下:閱讀以下c#**,回答問題:
[csharp]
view plain
copy
using
system;
using
system.collections.generic;
using
system.text;
namespace
findthenumber
; for
(int64 i = 1; i < int64.maxvalue; i++)
else
if(hit == 2)
else
break
;
} }
if((hit == 2) && (hit1 + 1 == hit2))
", i);
} }
} }
}
1> 這個程式要找的是符合什麼條件的數?
2> 這樣的數存在麼?符合這一條件的最小的數是什麼?
3> 在電腦上執行這一程式,你估計要多長時間才能輸出第乙個結果?時間精確到分鐘(電腦配置:單核cpu2.0ghz,記憶體和硬碟資源充足)
首先,rg[k]肯定大於15。若rg[k]<=15的話,那麼rg[k]*2也在rg陣列中,並且不能被 i 整除,所以這樣的 i 肯定找不到。
其次,rg[k]和rg[k+1]不能由其餘的rg陣列中的數組合相乘而得,比如18,可以由2乘上9得到,所以若 i 能整除 2 和 9, 則必能整除18. 由此,我們可以得到:16=2*8, 18 = 2*9, 20 = 4*5, 22 = 2*11, 24 = 3*8, 26 = 2*13, 28 = 4*7, 30 = 2*15。
這樣乍一看,似乎沒有滿足條件的rg[k]和rg[k+1],但是我們注意在上述一串等式中,16=2*8,其中的2是8的因子,所以只要 i 能整除8,就必能整除2,因此沒有必要要求 i 能整除 2*8。 而其餘的等式中,兩個乘數沒有因子關係,所以i 若能整除兩個乘數,則肯定能整除其乘積。
由此,我們得到了唯一滿足條件的rg[k]和rg[k+1],即16,17。
這樣,剩下的問題就是求不能整除16,17,卻能整除其餘所有數的整數中最小的那乙個。我們先把2到31中的素數都列出來(17除外):。而2到31中(16,17除外)的數都是由這些素數作為因子組合相乘得到的,其中,要得到8,至少要3個2,要得到27至少要3個3,要得到25,至少要2個5,其餘的素因子都只需乙個就夠了。
因此,這個最小的數就是 2^3, 3^3, 5^2, 7, 11, 13, 19, 23, 29, 31的乘積,答案為:2123581660200。(因為題目要求不借助電腦,所以我手算了兩次,竟然都算錯了,最後只好拿計算器算) 。
我們知道加法、判斷等操作基本都在幾個時鐘週期內就可以完成,而除法操作卻需要數十個時鐘週期,而取模操作也是通過除法操作得到的(還記得組合語言裡,執行除法操作之後,乙個暫存器裡存結果,另乙個暫存器裡存餘數),另外,對64位整數的除法明顯要慢於32位整數,綜合這些因素,我們可以假設該原子操作需要100個時鐘週期。因此2ghz的cpu在1秒內能跑2*10^9 / 100 = 2*10^7 即2000萬次原子操作,做過acm的同學就會有乙個直觀概念,這和我們通常做時限為1s的題時估算的計算次數差不多。
接下來估算原子操作執行的次數:外層迴圈跑了2123581660200次,內層迴圈取決於 i 的情況,當i為奇數的時候,內層最多跑5次即可結束,因為2,4,6都不能整除奇數;當i為偶數的時候,情況要複雜一些,但是也可以乙個乙個的詳細分析。這裡我們粗略估計,就算內層迴圈平均可以跑10次,外層迴圈少跑一些,去掉零頭,總的原子操作執行了2*10^13次。
所以需要 2*10^13 / (2*10^7) = 10^6秒約為277個小時。
程式設計之美讀書筆記2 20 程式理解和時間分析
1 理解這個程式就是從輸出的地方入手即可。這個程式輸出的條件是hit 2 hit1 1 hit2 而hit表示滿足i r j 0的條件的次數,hit 2表示這個條件只能被滿足兩次,也就是說對於乙個i,在rg陣列的30個數中,這個i能被其它28個數整除,而不能被其中兩個數整除。而hit1表示第乙個不能...
程式設計之美之程式理解和時間分析
這是 程式設計之美 的2.20題目,給出一段c 要求不用電腦,理解程式並回答問題。下面是從c 中改寫成的c cpp view plain copy include include using namespace std intmain for int64 i 1 i numeric limits i...
2 20 程式理解和時間分析
c 如下 include include include using namespace std int main void int hit 0,hit1 1,hit2 1 for int64 i 1 i int64 max i if else if hit 2 else if else else ...