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

2021-06-19 13:03:14 字數 1249 閱讀 5966

龐果程式設計大賽的題目

有兩個容器,容積分別為a公升和b公升,有無限多的水,現在需要c公升水。

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

可以進行的操作是:

把乙個容器灌滿;

把乙個容器清空(容器裡剩餘的水全部倒掉,或者倒入水缸);

用乙個容器的水倒入另外乙個容器,直到倒出水的容器空或者倒入水的容器滿。

問是否能夠通過有限次操作,使得水缸最後恰好有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

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;

int main()

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

歐幾里得演算法

歐幾里得演算法中,計算 x,y 的最大公約數的方法是輾轉相除,例如 26,15 26 15 1 11 15 11 1 4 11 4 2 3 4 3 1 1 3 1 3 0 可知,26,15 1 如果 x,y r,那麼有 ax by r,可以看出,上面的步驟實際上是可以直接得出 a,b 的 26 15...

歐幾里得演算法

輾轉相除法,又被稱為歐幾里德 euclidean 演算法,是求最大公約數的演算法。當然也可以求最小公倍數。以除數和餘數反覆做除法運算,當餘數為 0 時,取當前算式除數為最大公約數。可以使用遞迴實現,也可以使用迴圈實現。program algorithm code description 歐幾里得演算...

歐幾里得演算法

在 幾何原本 中,歐幾里得提出了用輾轉相除的方法求解兩個整數 a,b 的最大公約數的演算法 gcd a,b if 0 b return a else return gcd b,a mod b 定理 若整數 a,b 的最大公約數為 gcd a,b 那麼 gcd a,b gcd b,a mod b 證明...