泊松分酒問題
阿新 • • 發佈:2018-12-13
題目:
泊松是法國數學家、物理學家和力學家。他一生致力科學事業,成果頗多。有許多著名的公式定理以他的名字命名,比如概率論中著名的泊松分佈。
有一次閒暇時,他提出過一個有趣的問題,後稱為:“泊松分酒”。在我國古代也提出過類似問題,遺憾的是沒有進行徹底探索,其中流傳較多是:“韓信走馬分油”問題。
有3個容器,容量分別為12升,8升,5升。其中12升中裝滿油,另外兩個空著。要求你只用3個容器操作,最後使得某個容器中正好有6升油。
下面的列表是可能的操作狀態記錄:
12,0,0
4,8,0
4,3,5
9,3,0
9,0,3
1,8,3
1,6,5
每行3個數據,分別表示12,8,6升容器中的油量
第一行表示初始狀態,第二行表示把12升倒入8升容器後的狀態,第三行是8升倒入5升,...
當然,同一個題目可能有多種不同的正確操作步驟。
本題目的要求是,請你編寫程式,由使用者輸入:各個容器的容量,開始的狀態,和要求的目標油量,程式則通過計算輸出一種實現的步驟(不需要找到所有可能的方法)。如果沒有可能實現,則輸出:“不可能”。
例如,使用者輸入:
12,8,5,12,0,0,6
使用者輸入的前三個數是容器容量(由大到小),接下來三個數是三個容器開始時的油量配置,最後一個數是要求得到的油量(放在哪個容器裡得到都可以)
則程式可以輸出(答案不唯一,只驗證操作可行性):
12,0,0
4,8,0
4,3,5
9,3,0
9,0,3
1,8,3
1,6,5
每一行表示一個操作過程中的油量狀態。
import java.util.Scanner; public class Bosongfenjiu { private int v1,v2,v3,c1,c2,c3,m; private int i=0; public Bosongfenjiu() { System.out.println("使用者輸入7個數字,使用逗號分隔:"); Scanner sc=new Scanner(System.in); String str=sc.next(); String[] number=str.split(","); v1=Integer.valueOf(number[0]); v2=Integer.valueOf(number[1]); v3=Integer.valueOf(number[2]); c1=Integer.valueOf(number[3]); c2=Integer.valueOf(number[4]); c3=Integer.valueOf(number[5]); m=Integer.valueOf(number[6]); Backtrack(c1, c2, c3); } public void Backtrack(int cur1,int cur2,int cur3) { i++; System.out.println(cur1+" "+cur2+" "+cur3); if(cur1 == m || cur2 == m || cur3 == m) //如果有一瓶為6,則停止分酒 { System.out.print("找到!"); return; } else if(cur1==c1&&cur2==c2&&cur3==c3&&i!=1) { System.out.println("不可能!"); return; } if(cur2 != 0 && cur3 != v3) { //瓶子2有酒並且瓶子三不滿 if(cur2 + cur3 <= 5) Backtrack(cur1,0,cur2+cur3);//如果2和3的總和小於3的容量,把瓶2的酒給了瓶3 else Backtrack(cur1,cur2-(5-cur3),v3);//否則,從2中取出適量將3填滿 } else if(cur3 == v3) {//瓶子3滿的,這時就要把酒倒入到瓶子1中 if(cur3 + cur1 <= v1) Backtrack(cur1+cur3,cur2,0); //如果1和3的總和小於1的容量,將3倒入1中 else Backtrack(v1,cur2,cur3-(v1-cur1)); //否則,從3取出適量將1填滿 } else if(cur2 == 0) { //當瓶子2是空的時候從瓶子1倒入酒 if(cur1 >= v2) Backtrack(cur1-v2,v2,cur3); //如果1中大於2容量,則將2填滿,1中有剩餘 else Backtrack(0,cur1,cur3); //如果1中小於2,則全部倒入2中即可 } } public static void main(String[] args) { new Bosongfenjiu(); } }