1. 对任意整数a,b和他们的最大公约数d,关于未知数x和y的线性丢番图方程(称为裴蜀等式)
ax+by=m有整数解的时候当且仅当m是d的倍数
裴蜀公式有解的时候必然有无穷多个整数解,每组解x,y都称为裴蜀数,可以用欧几里得算法求得
特别地ax + by = 1 有整数解当且仅当整数a和b互为素数
在求解线性方程组ax + by = k的时候求解最大公约数
由其中的过程递推出如下的规律:
往下求解最大公约数的过程中,x1和y1分别是下一次的x和y
例如线性方程:2x + 7y = 1求解整数解
可以知道a = 2, b = 7依次求出最大公约数(使用递归来解决)
(2,7)
(7,2)
(2,1)
(1,0)
最后结束递归得到x1 = 1 y1 = 0但是此时的a和b不是原来的a和b了,需要往上来递推得到新的x1和y1
那么可以得到
(2,7) x1 = -3 y1 = 1
(7,2) x1 = 1 y1 = -3
(2,1) x1 = 0 y1 = 1
(1,0) x1 = 1 y1 = 0
层层往上推最后得到原来的x和y,那么这样就可以使用递归更新解决x1和y1来最终得到线性方程组的一组整数解
2. 代码如下:
public class Main {
static long x;
static long y;
public static void main(String[] args) {
try {
linearEquation(48, 24, 24);
System.out.println(x+" "+y);
} catch (Exception e) {
System.out.println("无解");
}
}
public static long ext_gcd(long a,long b){
if(b==0){
x = 1;
y = 0;
return a;
}
long res = ext_gcd(b,a%b);
long x1 = x;
x = y;
y = x1 - (a/b)*y;
return res;
}
public static long linearEquation(long a,long b,long m) throws Exception{
long d = ext_gcd(a,b);
if(m%d!=0){
throw new Exception("无解");
}else{
long n = m / d;
x *= n;
y *= n;
}
return d;
}
public static long inverseElement(int a,int b) throws Exception{
long d = ext_gcd(a,b);
x = (x % b + b) % b;
//System.out.println(d+" "+x+" "+y);
if(a%b==0){
throw new Exception("无解");
}
return d;
}
public static long inverseElement2(long a, long mo) throws Exception {
long d = linearEquation(a, mo, 1);//ax+mo*y=1
x = (x % mo + mo) % mo;//保证x>0
return d;
}
}