1. 程式人生 > >泊松分酒問題

泊松分酒問題

題目:

    泊松是法國數學家、物理學家和力學家。他一生致力科學事業,成果頗多。有許多著名的公式定理以他的名字命名,比如概率論中著名的泊松分佈。

    有一次閒暇時,他提出過一個有趣的問題,後稱為:“泊松分酒”。在我國古代也提出過類似問題,遺憾的是沒有進行徹底探索,其中流傳較多是:“韓信走馬分油”問題。

    有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();
    }  
}