1. 程式人生 > >【Java實踐】十二小球天平三次稱重問題

【Java實踐】十二小球天平三次稱重問題

十二個小球用天平三次稱重找出其中唯一一個質量不同(或輕或重)的小球,用java程式碼實現。 思路:
將十二個小球分別標記為A,B,C,D,E,F,G,H,I,J,K,L,將它們以四個為一組分為三組也就是:第一組:ABCD;第二組:EFGH;第三組:IJKL。
首先我們考慮將第一組和第二組放置在天平兩端進行稱重(第一次稱重),根據稱重的結果可分為兩種情況:相等和不等。下面會分別介紹兩種情況以及後續判斷。
1. 第一組與第二組相等。
這是最簡單的情況,可以看出顯然第一組的四個小球ABCD和第二組的小球EFGH都是正常小球,而質量不同的小球在第三組IJKL中。那麼第一組和第二組的8個小球可以作為標準球來使用。
將第三組的四個小球IJKL分成再次分成兩組,兩兩一組。組1,IJ;組2,KL。從第一組裡抽出AB組成組3,作為標準球的對照組。
先用組1和組3稱重(第二次稱重)。
(1) 組1和組3相等。
則不同的小球在組2——K,L——之中。
之後用K與組3中抽出的A稱重(第三次稱重)。
如果相等,則不同的小球為L,若不等則不同的小球為K。
(2)組1和組3不等。
則不同的小球在組1——I,J——之中。
之後用I和組3抽出的標準球A稱重(第三次稱重)。
如果相等,則不同小球為J;若不等則不同小球為I。
2. 第一組和第二組不等。
這個情況要比上面的複雜的多了,因為根據稱重結果第三組IJKL沒有任何問題,不同的小球在第一組和第二組的八個球之中,那麼我們剩餘的兩次稱重必須要處理8個小球。
首先我們繼續把ABCDEFGH八個小球分為332三組:組1,ABE;組2,CDF;組3,GH;這樣我們能從第二次稱重中得到最重要的資訊,然後稱重組1和組2(第二次稱重).
(1)組1和組2相等。
則不同的小球在組3裡。
之後從第三組裡抽出標準球I和組3的G進行稱重(第三次稱重)。
如果相等,則不同小球為H,若不等則不同小球為G。
(2)組1和組2不等且傾斜與第一組和第二組稱量時相同(即滿足第一組>第二組且組1>組2,或第一組<第二組且組1<組2)。
若第二次稱重的傾斜狀況和第一次相同,說明有問題的小球沒有改變位置,則小球E和小球CD是正常小球,質量不同的小球在ABF中間。
之後稱重A和B。(第三次稱重)
如果AB相等,那麼必然是F重量不同。若AB不等,則說明AB質量不同,看此時的傾斜狀況是否和第一組一致,那麼意味著有問題的小球還是放在和第一次稱重同一邊,則是A有問題。
(3)組1和組2不等且傾斜與第一組和第二組稱量時相反(即滿足第一組>第二組且組1<組2,或第一組<第二組且組2>組1)。
若第二次稱重和第一次稱重傾斜狀況不同則表明質量不同的小球換邊了,那麼小球E和小球CD中有質量不同的小球,ABF是沒有問題的。
之後稱重CD(第三次稱重)。
如果CD相等,那麼顯然是E重量不同,若是CD不相等,那麼對比CD與第一次稱重的傾斜方向,若是傾斜方向一致,則說明C有問題,不一致則說明D有問題。
好了,從原理上看,十二小球用天平稱三次的解決方案就是以上邏輯。那麼接下來看看程式碼怎麼寫

先寫小球類 12345678910111213141516171819202122232425262728293031323334353637383940一個實體類是一個小球,有小球自帶的兩個屬性,編號和重量。之後我們寫一些方法,呼叫這些方法可以對多個或單個小球進行稱重。 1
/**
2
 * 0 等於, 1大於,-1小於
3
 * @param list1
4
 * @param list2
5
 * @return
6
 */
7
private static int balence(List<Ball> list1, List<Ball>list2) {
8 9
double weight1 = 0;
10
double weight2 = 0;
11 12
// weight1
13
for(Ball item : list1) {
14
weight1 = weight1+item.getWeight();
15
}
16 17
// weight2
18
for(Ball item : list2) {
19
weight2 = weight2+item.getWeight();
20
}
21 22
return weight1==weight2?0:(weight1>weight2?1:-1);