2018-03-11 17:39:22
一、辗转相除法
在数学中,辗转相除法,又称欧几里得算法(英语:Euclidean algorithm),是求最大公约数的算法。辗转相除法首次出现于欧几里得的《几何原本》(第VII卷,命题i和ii)中,而在中国则可以追溯至东汉出现的《九章算术》。辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的差的最大公约数。例如,252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);因为252 − 105 = 21 × (12 − 5) = 147,所以147和105的最大公约数也是21。在这个过程中,较大的数缩小了,所以继续进行同样的计算可以不断缩小这两个数直至其中一个变成零。这时,所剩下的还没有变成零的数就是两数的最大公约数。由辗转相除法也可以推出,两数的最大公约数可以用两数的整数倍相加来表示,如21 = 5 × 105 + (−2) × 252。这个重要的结论叫做裴蜀定理。
辗转相除法处理大数时非常高效,如果用除法而不是减法实现,它需要的步骤不会超过较小数的位数(十进制下)的五倍。拉梅于1844年证明了这点,同时这也标志着计算复杂性理论的开端。
public int GCD(int a, int b){
while(b != 0 ){
int temp = b;
b = a%b;
a = temp;
}
return a;
}
二、裴蜀定理
在数论中,裴蜀等式(英语:Bézout's identity)或裴蜀定理(Bézout's lemma)是一个关于最大公约数(或最大公约式)的定理。裴蜀定理得名于法国数学家艾蒂安·裴蜀,说明了对任何整数a,b和m,关于未知数x和y的线性丢番图方程(称为裴蜀等式):
有整数解时当且仅当m是a和b的最大公约数的倍数。
裴蜀等式有解时必然有无穷多个整数解,每组解x和y都称为裴蜀数,可用扩展欧几里得算法求得。 x {\displaystyle x} 、 y {\displaystyle y}
都称为裴蜀数,可用扩展欧几里得算法求得
例如,12和42的最大公约数是6,则方程
有解。事实上有(-3)×12 + 1×42 = 6及4×12 + (-1)×42 = 6。
三、Water and Jug Problem
问题描述:
问题求解:
如果单纯的去思考两个杯子之间的倒来倒去,那么问题就会变得非常复杂。有一种简化思路是,考虑有一个大的杯子,而x,y只是向大杯子中添加或者取出水,如果最终大杯子中数目等于给定的数,那么返回TRUE。
其实就是寻找z = ax + by等式是否有解,也就是规约到了裴蜀定理的概念中,只需要判断z % GCD(x, y)即可。
public boolean canMeasureWater(int x, int y, int z) {
//limit brought by the statement that water is finallly in one or both buckets
if(x + y < z) return false;
//case x or y is zero
if( x == z || y == z || x + y == z ) return true;
//get GCD, then we can use the property of Bézout's identity
return z%GCD(x, y) == 0;
}
public int GCD(int a, int b){
while(b != 0 ){
int temp = b;
b = a%b;
a = temp;
}
return a;
}
为什么这样是可行的,这里有一份证明: