C趣味程序百例(25)波松瓦酒的分酒趣題

字號:

77.波松瓦酒的分酒趣題
     法國數(shù)學(xué)家波瓦松在表年時代研究過一個有趣的數(shù)學(xué)問題:某人有12品脫的啤酒一瓶,想從中倒出6品脫,但他沒有6品脫的容器,僅有一個8品脫和5品脫的容器,怎樣倒才能將啤酒分為兩個6品脫呢?
    *問題分析與算法設(shè)計
     將12品脫酒 8品脫和5品脫的空瓶平分,可以抽象為解不定方程:
     8x-5y=6
     其意義是:從12品脫的瓶中向8品脫的瓶中倒x次,并且將5品脫瓶中的酒向12品脫的瓶中倒y次,最后在12品脫的瓶中剩余6品脫的酒。
     用a,b,c代表12品脫、8品脫和5品脫的瓶子,求出不定方程的整數(shù)解,按照不定方程的意義則倒法為:
     a -> b -> c ->a
     x y
     倒酒的規(guī)則如下:
     1) 按a -> b -> c ->a的順序;
     2) b倒空后才能從a中取
     3) c裝滿后才能向a中倒
     按以上規(guī)則可以編寫出程序如下:
    *程序與程序注釋
    #include
    void getti(int a,int y,int z);
    int i; /*最后需要分出的重量*/
    void main()
    {
     int a,y,z;
     printf("input Full a,Empty b,c,Get i:"); /*a 滿瓶的容量 y:第一個空瓶的容量 z:第二個空瓶的容量*/
     scanf("%d%d%d%d",&a,&y,&z,&i);
     getti(a,y,z); /*按a -> y -> z -> a的操作步驟*/
     getti(a,z,y); /*按a -> z -> y -> a的步驟*/
    }
    void getti(int a,int y,int z) /*a:滿瓶的容量 y:第一個空瓶的容量 z:第二個空瓶的容量*/
    {
     int b=0,c=0; /* b:第一瓶實際的重量 c:第二瓶實際的重量*/
     printf(" a%d b%d c%d\n %4d%4d%4d\n",a,y,z,a,b,c);
     while(a!=i||b!=i&&c!=i) /*當(dāng)滿瓶!=i或另兩瓶都!=i*/
     {
     if(!b)
     { a-=y; b=y;} /*如果第一瓶為空,則將滿瓶倒入第一瓶中*/
     else if(c==z)
     { a+=z; c=0;} /*如果第二瓶滿,則將第二瓶倒入滿瓶中*/
     else if(b>z-c) /*如果第一瓶的重量>第二瓶的剩余空間*/
     { b-=(z-c);c=z;} /*則將裝滿第二瓶,第一瓶中保留剩余部分*/
     else{ c+=b; b=0;} /*否則,將第一瓶全部倒入第二瓶中*/
     printf(" %4d %4d %4d\n",a,b,c);
     }
    }