用歐幾里得演算法解決倒水問題
龐果程式設計大賽的題目
有兩個容器,容積分別為A升和B升,有無限多的水,現在需要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 <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 //提示:自動閱卷結束唯一標識,請勿刪除或增加。
總得來說,雖然這個題目不是很難,但是有助於對於這一類問題的解決,謹以此文加深點印象。