扩展欧几里得算法

本文通过实例讲解了如何使用扩展欧几里得算法求解特定类型的线性方程,并提供了一种方法来找到使给定表达式成为整数的最小k值。

返回gcda,bgcd(a,b),并计算方程:ax+by=gcd(a,b)ax+by=gcd(a,b)的一个解

#include<stdlib.h>
#include<stdio.h>
int e_gcd(int a, int b, int * x, int *y) {
    if (b == 0) {
        *x = 1;
        *y = 0;
        return a;
    }
    int ans = e_gcd(b, a%b, x, y);
    int temp = *x;
    *x = *y;
    *y = temp - a / b*(*y);
    return ans;
}
int main() {
    int a = 8, b = 3;
    int x, y;
    int result = e_gcd(a, b, &x,&y);
    printf("gcd(%d,%d)=%d,%d*a+%d*b=%d", a, b, result, x, y, result);
    return 0;
}


intint a,b,m>0a,b,m>0,求使a+kbmk:a+kbm是整数的最小的k:
想法:比如 8+4k6=t<=>6t4k=88+4k6=t<=>6t−4k=8(∗)
6x4y=gcd(6,4)=2x0,y0先求解6x−4y=gcd(6,4)=2的一组解(x0,y0),这是扩展欧几里得算法
使8agcd(m,k)=82,两边乘以某个数,使得8出现在右边,这里乘以agcd(m,k)=82,
64x04(4y0)=8,(4x0,4y0)等式变为6(4x0)−4(4y0)=8,我们这样主要为了得到(∗)的一组解(4x0,4y0)而已
然后就可以的到所有解:
设有两组解:6x14y1=86x1−4y1=8,6x24y2=86x2−4y2=8,相减:

6(x1x2)=4(y1y2)6(x1−x2)=4(y1−y2)
,发现了所有解的规律,
x=x0+mgcd(m,b)tx=x0+mgcd(m,b)t

y=y0+bgcd(m,b)ty=y0+bgcd(m,b)t
,注意这里的y前面是负号,扩展欧几里得的负号是正的,选出需要的那个最小的y就不说了。
#include<stdlib.h>
#include<stdio.h>
int e_gcd(int a, int b, int * x, int *y) {
    if (b == 0) {
        *x = 1;
        *y = 0;
        return a;
    }
    int ans = e_gcd(b, a%b, x, y);
    int temp = *x;
    *x = *y;
    *y = temp - a / b*(*y);
    return ans;
}
int min_k(int a, int b, int m) {//求(a+kb)/m是整数中最小的k
    int x = 0, y = 0;
    int k1 = e_gcd(m, b, &x, &y);
    if (a%k1 != 0) printf("无解\n"); exit(0);
    y *= a / k1;//这是一个特解
    y = -(((y%(m/k1))-(m/k1))%(m/k1));
    return y;
}
int main() {
    int ress=min_k(6, 4, 5);
    printf("%d\n", ress);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值