《演算法競賽入門經典(第二版)》習題解析 第二章

2021-10-02 18:28:51 字數 4429 閱讀 6597

題目:

輸出100-999中的所有水仙花數。若3位數abc滿足abc=a3+b3+c3

,則稱其為水仙花數。例如153=13+53+33,所以153是水仙花數。

解析:

採用暴力搜尋的思想,窮盡所有可能的解。

**

#include

#include

intmain()

}}return0;

}

題目:相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先後以三人一排、五人一排、七人一排地變換隊形,而他每次只掠一眼隊伍的排尾就知道總人數了。輸入包含多組資料,每組資料報含3個非負整數a,b,c,表示每種隊形排尾的人數(a<3,b<5,c<7),輸出總人數的最小值(或報告無解)。已知總人數不小於10,不超過100。輸入到檔案結束為止。

樣例輸入:

2 1 6

2 1 3

樣例輸出:

case 1: 41

case 2: no answer

解析1:

分析題意,即表示求解最小總人數s(10≤s≤100),分別對3、5、7取余為a,b,c,實際上也是一種暴力搜尋。關於檔案結束,在參考不同的答案時有人根據其標誌為eof,所以while的條件為while (scanf ("%d%d%d",&a,&b,&c) != eof),但此題中我用了重定向的方法,故迴圈條件為while(scanf("%d%d%d",&a,&b,&c)==3)。

**如下:

#include

intmain()

}if(i>

100)

printf

("no answer\n");

}return0;

}

解析2

此題更巧妙的方法是用最小公倍數,明朝數學家程大位在他所著的《演算法統宗》中就暗示了此題解法:

三人同行七十稀,

五數梅花甘一枝,

七子團圓正半月,

除百零五便得知。

甘一是21,正半月是15,除百零五的意思就是求105的餘數。可以發現35是5和7的最小公倍數,21是3和7的最小公倍數,15是3和5的最小公倍數,105是3、5、7的最小公倍數。因此這四句口訣的意思就是用任意兩數的最小公倍數乘第三個數後三項進行求和,對和求105的餘數即可得到答案。

**如下:

#include

int main ()}

if(i >

100)

printf (

"no answer\n");

}return0;

}

題目:輸入正整數n≤20,輸出乙個n層的倒三角形。

解析:

找出三角形的規律即可。第i(i從1開始,從上往下數)行有(2i-1)個「 * 」,和(n-i)個空格,利用迴圈便可完成此題。

**:

#include

intmain()

}return0;

}

題目:樣例輸入:

2 465536 655360

0 0樣例輸出:

case 1: 0.42361

case 2: 0.00001

解析:

從題意可知,本題的核心思想仍然為迴圈,但注意題目所說「有陷阱」,在可以看出陷阱主要體現在資料的型別和範圍中,下面我們根據題意第一次編寫**。

**(有bug版):

#include

intmain()

s=0;

for(

int i=n;i<=m;i++

) s+

=1.0

/(i*i)

;printf

("case %d: %.5lf"

,++kase,s);}

return0;

}

我們來看下執行結果:

我們可以看出,第一行資料輸出結果和預期一致,由此判斷程式基本邏輯沒有問題。但是,在第二個資料出現了「#info」的字樣,這是由於當m=655360時,普通的int型資料無法表示最大值達到106 * 106=1012級別的整數,產生溢位問題,使得i * i值在截斷為int時結果為0而出現「被0除」的錯誤,一種方法可將n,m,i的型別直接定義為long long型,另一種更為巧妙的方法是將s+=1.0/(i*i);改為s+=1.0/i/i;

題目:

輸入正整數a,b,c,輸入a/b的小數形式,精確到小數點後c位。a,b≤106,c≤100。,輸入包含多組資料,結束標記為a=b=c=0

樣例輸入:

1 6 4

0 0 0

樣例輸出:

case 1: 0.1667

解析:

本題的關鍵即為輸出的小數字數需要程式來控制,我們需要自己寫程式模擬保留小數字數的過程(注意四捨五入),可以根據我們進行除法運算的過程:拿樣例1/6舉例,先求出他們的商,既1÷6=0······1。商為0餘數為1。那麼此時就列印出」0.」來。此時應該算十分位,所以餘數1應該乘以10為10,10÷6=1······4。商為1餘數為1。此時列印出來「1」來。則輸出的為「0.1」。再算百分位:40÷6=6······4,商為6餘數為4。此時列印出「6」。輸出介面輸出「0.16」。以上辦法得出千分位和萬分位。輸出介面輸出結果為「0.1666」。此時就有四位小數,但是還要檢查最後一位是否為四捨五入。再次計算十萬分位,發現商為6,那麼萬分位就要進一。最後結果為「0.1667」。

**:

#include

intmain()

if(((a*10)

%b)*

10/b<5)

//當第c+1位小於5時,正常輸出結果(四捨)

elseif(

(a*10

)/b!=9)

//當c+1位大於等於5且第c位不為9時,輸出時第c位的結果需要加一 (五入)

elseif(

(a*10

)/b==9)

//當c+1位大於等於5且第c位為9時,需要依次向前進製。

else

break;}

if(s[1]

==0) z++

;printf

("case %d:%d."

,++n,z)

;for

(int i=

1;i<=c;i++

)printf

("%d"

,s[i]);

}}return0;

}

說明:**邏輯基本沒有問題,但不夠簡潔,能力有限暫且沒有寫出更好的方法,不足之處還請指教!

題目:解析:

提示的意思就是讓我們直接用暴搜找出符合條件的數就好了。根據題目要求,可以用到的最小的數(作為abc)是123,最大的數(作為ghi)是987,由最大數可以根據3個數的比例推算出最小數abc的上限為987÷3=329,因此最小數abc的範圍是123~329。

求解關鍵: 九個數加起來是45,相乘是362880,這兩個數是不變的,根據這兩個條件求解。

**(簡單版):

#include

intmain()

}}

**(高階版):

#include

#include

void

result

(int num,

int*result_add,

int*result_mul)

intmain()

return0;

}

演算法競賽入門經典(第二版) 習題

習題2 5 include int main if 10 n b 10 b 5 確定末位四捨五入的情況 printf d 10 n b 1 else printf d 10 n b return 0 注意 要及時輸出,防止n越界 習題2 6 include void result int num,i...

《演算法競賽入門經典(第二版)》習題(二)

習題 2 1 水仙花數 輸出100 999中的所有水仙花數。若3位數abc滿足abc a b c 則稱其為水仙花數。例如 153 1 5 3 所以153是水仙花數。include intmain return0 習題 2 2 韓信點兵 相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先後以三...

演算法競賽入門經典 (第二版)習題2 6

用 1,2,3 9組成三個數字abc,def,ghi每個數字恰好使用一次,要求 abc def ghi 1 2 3按照 abc def ghi 的格式輸出所有解 每行乙個解。思路 有a,b,c三個變數,先確定a的範圍,最小的數且符合題目規定的數字為123,最大的數字且符合題目規定的數字是987 所以...