1.問題描述
一天商人不小心把40磅重的砝碼摔成4部分,發現4部分砝碼的重量都是整磅數,而且可以用它們稱出任意1-40之間的整數磅質量,問這四塊砝碼各重多少磅?
2.該問題的數學分析
①必須有1磅的砝碼,否則39磅的重量無法稱出.
②有了1磅的砝碼後,再加上乙個3磅的砝碼,可稱出2~4磅的重量.
③有了1磅和3磅的砝碼後,再加上乙個9磅的砝碼,可稱出5~13磅的重量.
④有了1、3、9磅的砝碼後,再加上乙個27磅的砝碼,可稱出14~40磅的重量.
所以這4塊砝碼碎片分別是1、3、9、27磅,即首項為1,公比為3的等比數列.
看了數學家的邏輯分析,是不是覺得很有道理,可就是不會,沒關係,我們可以用很笨的計算機來算出答案。
3.程式設計解決問題
首先對該問題抽象數學模型:設這四塊砝碼的質量分別為a, b, c, d;則有
(1)a+b+c+d = 40(abcd為1-37之間的正整數,且互不相等)
(2)abcd可以組合算出(只能加減)1-40之間的任意整數
4.分析問題
(1) 對於(1)問題,a,b,c,d互補等於40且各不相等,一般的,我們會想到窮舉法列出以下的程式(c語言):
int a, b, c, d;
int count = 0;
for (a=1; a<=37; a++)
for (b=1; b<=37; b++)
for (c=1; c<=37; c++)
for (d=1; d<=37; d++)
if ( (a+b+c+d == 40) && (a!=b)&&(a!=c)&&(a!=d) &&(b!=c) &&(b!=d) &&(c!=d) )
實際上這樣的方式不僅運算量較大,而且得出的答案會有4!種重複(實際會得出7128種答案),這是因為這種窮舉考慮了排列方式,比如10,8,9,13實際上會出現4!種排列,所以很沒有效率。下面這種經典的演算法可以解決這個問題。
int a, b ,c ,d;
int count = 0;
for (a=1; a<=40; a++)
for (b=a+1; b<=40-a; b++)
for (c=b+1; c<=40-a-b; c++)
for (d=c+1; d<=40-a-b-c; d++ )
if (a+b+c+d == 40)
count輸出為297,這種演算法的有趣之處在與它確保了內層迴圈搜尋範圍始終小於外層迴圈,而且不會出現數相等的情況。關於它的數學證明(暫時不懂,有興趣可以查閱相關資料)。
(2)關於數字組合的問題,也可以使用窮舉法,先列出方程
w1*a+ w2*b+ w3*c+ w4*d = 40( w1,w2,w3,w4屬於 )
這個方程很好理解,每塊砝碼可以不放,引數為0,;放在右邊引數為1(左物右碼),放在左邊為-1.
下面是窮舉法**:
int w1, w2, w3, w4;
int weight;
for (w1=-1; w1<=1; w1+=1)
for (w2=-1; w2<=1; w2+=1)
for (w3=-1; w3<=1; w3+=1)
5.下面是完整的c語言程式
之破碎的砝碼問題原始碼
6.總結
通過這個有趣的數學問題,我們可以學到很多東西,當然除了機靈的數學邏輯分析之外,我們對列舉的用法是不是又深入了一些了呢?
破碎的砝碼問題
法國數學家梅齊亞克在它的 數學組合遊戲 中提出了這樣乙個問題 乙個商人有乙個重量為40磅的砝碼,有一天他不小心將該砝碼摔成了4塊。商人發現每塊砝碼的重量都是整磅數,而且每塊砝碼的重量各不相同,並且發現這四塊砝碼碎片可以在天平上稱出1 40磅之間的任意重量 整磅數 問這四塊砝碼碎片的重量各是多少?1 ...
C語言窮舉法解決破碎的砝碼
1.問題描述 一天商人不小心把40磅重的砝碼摔成4部分,發現4部分砝碼的重量都是整磅數,而且可以用它們稱出任意1 40之間的整數磅質量,問這四塊砝碼各重多少磅?2.該問題的數學分析 必須有1磅的砝碼,否則39磅的重量無法稱出.有了1磅的砝碼後,再加上乙個3磅的砝碼,可稱出2 4磅的重量.有了1磅和3...
稱砝碼問題
有一組砝碼,重量互不相等,分別為m1 m2 m3 mn 它們可取的最大數量分別為x1 x2 x3 xn 現要用這些砝碼去稱物體的重量 問能稱出多少種不同的重量。input 測試資料第一行乙個整數n n 10 表示有多種不同的砝碼 第二行n 個整數 中間用空格分隔 m1 m2 m3 mn 分別表示 n...