1. 程式人生 > >百錢買百雞問題,買雞問題的解決方案

百錢買百雞問題,買雞問題的解決方案

 百雞百錢問題

設母雞每隻5元,公雞每隻3元,小雞1元3只。現用100元買100只雞,求出所有可能的解。

答案  注:
X表母雞 ,Y表公雞,  Z表小雞,
X=0, Y=25,  Z=25
X=4, Y=18,  Z=26
X=8, Y=11,  Z=27
X=12, Y=4,  Z=28 

解決這個問題肯定是沒有問題滴,不過要看你的解決方案的效率。

最原始的想法應該是用三個for迴圈去實現:
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
for(int k= 0 ;k<100;k++)
{
if((i+j+3*k==100)&&(5*i+3*j+k==100))
{
System.out.println("X=" + i + ", Y=" + j + ",  Z="
+ k);
}
}
}
}

優化一:(喜哥最初方案)
for (int i = 0; i < 20; i++)

{
for (int j = 0; j < 30; j++)
{
for(int k= 0 ;k<100;k=k+3)
{
if((i+j+k==100)&&(5*i+3*j+k/3==100))
{
System.out.println("X=" + i + ", Y=" + j + ",  Z="
+ k/3);
}
}
}
}
優化二:(我方案)
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 33; j++)
{
if (((100 - i - j) % 3 == 0)
&& ((100 - i - j) / 3 + 5 * i + 3 * j == 100))
{
System.out.println("X=" + i + ", Y=" + j + ",  Z="
+ (100 - i - j) / 3);
}
}
}

優化三:(巨集偉方案)
for (int i = 0; i <= 20; i++)
{
for (int j = 0; j <= 33; j++)
{
if ((100 - i*5 - j*3)*3 + i + j == 100)
{
System.out.println("X=" + i + ", Y=" + j + ",  Z="
+ (100 - i - j) / 3);
}
}
}

優化四(執行時間相當最少)
for (int i = 0; i <=12; i++)
{
for (int j = 0; j <= 25; j++)
{
if ((100 - i*5 - j*3)*3 + i + j == 100)
{
System.out.println("X=" + i + ", Y=" + j + ",  Z="
+ (100 - i - j) / 3);
}
}
}

現在來分析下上面幾種方案,
首先是最原始方案,這是最容易想到的方法。一拿到這個題目時我最初的想法也是用三個迴圈去實現。但真正去實現時候,卻直接跳過去了。至於實現時自己為啥沒想用此方法,估計是已經受到思想潛移默化的影響,將其直接忽視,跳入下一較優化的思想
方案。最原始的方案思想就是將所有組合一一列出,不管其是否是多餘的,然後一一判斷將滿足條件的方案打印出來。
優化一:大大縮小了不可能滿足條件的組合。執行效率提高了一半還多。但還是有改善餘地。
優化二、三:乍一看跟巨集偉的差不多,其實不然,特別是if判斷語句,鴻偉裡面只用到了加減乘運算子,而我多加了除和餘運算,後面巨集偉告訴我才知道運算子執行效率問題,之前根本就沒這個意識。加減乘除執行效率依次降低,執行時間依次增加。直接移位的執行效率相對較高,這讓我聯想到安哥程式裡面多次用到了左移與右移來實現整型與陣列型之間的轉換,原來這也跟執行效率有關係滴。從巨集偉程式裡面顯然反映出來了,如果我們還不瞭解此方面知識,是感受不到它的精簡之所在。
優化四的話,是先從數學角度算出了他們的範圍,然再想出來滴。實際意義可能小了點,但也不失為一種好的解決方案。

窮舉法,易堅一直談到它的精髓,我的理解是窮舉就是將所有可能的結果一一找出,然後在從中找到符合要求的答案。至於它的精髓,我目前的理解是將其靈活運用到實際問題的解決中去,使之成為自己的一種思想工具。後上網查了下差不多是這個概念。它常用於密碼破譯,有人稱為暴力破解法。巨集偉在此基礎上有了自己新的理解,他將其發散性地運用到實際問題解決中。面對一個問題他可能會想到多種解決方案,然後將其羅列出來,相當於窮舉所有的解決方案,然後在預估每一種方案的可行性和效率問題,最後選出自認為最易實現的方案執行。在此也提出來供大家參考分享下。