用歐幾里得算法解決倒水問題

龐果編程大賽的題目

有兩個容器,容積分別爲A升和B升,有無限多的水,現在需要C升水。

我們還有一個足夠大的水缸,足夠容納C升水。起初它是空的,我們只能往水缸裏倒入水,而不能倒出。

可以進行的操作是:

  1. 把一個容器灌滿;
  2. 把一個容器清空(容器裏剩餘的水全部倒掉,或者倒入水缸);
  3. 用一個容器的水倒入另外一個容器,直到倒出水的容器空或者倒入水的容器滿。
    問是否能夠通過有限次操作,使得水缸最後恰好有C升水。


輸入:三個整數A, B, C,其中 0 < A , B, C <= 1000000000

輸出:0或1,表示能否達到要求。

這種倒水問題肯定不是第一次碰到,這次碰到了,一定要弄出個究竟!

首先我想到的是方程Ax+By=C,A、B、C均爲整數,有沒有x,y的整數解的模型。

結果意外發現了歐幾里得算法早就運用於解決此類問題了。

歐幾里得算法的目的是計算兩個正整數A、B的最大公約數,計算過程可以描述爲:

1、計算res=A%B,A對B取餘;

2、若res爲0,則最大公約數爲B;

3、若res不爲0,則進行賦值A=B,B=res,繼續第一步。

計算過程清晰了,相應的函數寫法也很明顯了,我想到了主要是兩種方式:

1、直接循環

int res(int a,int b)

{

 while(res=a%b)

    {

       a=b;

       b=res;

    }

return b;

}

退出循環後的b值即是所求的最大公約數。

2、遞歸寫法

int res(int a,int b)

{

 return b?res(a,a%b):a;

}

有一次感受到了不理解、不會用遞歸就註定得多敲鍵盤的道理啊。

說了歐幾里得算法,我們重歸正題,求出了A和B的最大公約數之後,怎麼判斷倒水是否能成功呢?

很簡單,如果C能被最大公約數整除,則有辦法可以倒水成功;否則就沒有辦法。

以下是編程挑戰賽上我的代碼

#include <stdio.h>

int can(int a,int b,int c) {

   int res;

   while(res=a%b)

    {

       a=b;

       b=res;

    }

   printf("%d\n",b);

   if(c%b==0)

   return 1;

   else

   return 0;

}

//start 提示:自動閱卷起始唯一標識,請勿刪除或增加。

int main()

{

   printf("%d",can(4,6,7));

}

//end //提示:自動閱卷結束唯一標識,請勿刪除或增加。

總得來說,雖然這個題目不是很難,但是有助於對於這一類問題的解決,謹以此文加深點印象。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章