求公因数——欧里几何算法

145 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情


公约数(gcd)有这几种比较常规的算法——辗转相除法或者是辗转相减法

辗转相除法:

image.png

辗转相减法:

image.png

拓展欧里几何算法:

然而有欧里几何算法的拓展版,在离散数学中有这样的定义:

已知任意正整数a,b,拓展欧里几何算法可以在求得a,b的最大公约数的同时,能找到整数x, y(其中一个很可能是负数),是他们满足下边的等式: image.png

代码呈现

//x和y分别是a和b的系数
int Exgcd(int a,int b,int& x,int& y){
    if(b==0){
        x=1;
        y=0;
        return 0;
    }
    int d=Exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

正所谓没有题目就没有灵魂,好的上题目~

题目名称:

7-7 h0054. 欧几里得的问题(10 分)

题目描述:

由欧几里得的辗转相除法可知,对于任何正整数 A
和 B ,都存在这样的整数 X 和 Y , AX+BY=D ,其中 D 是
A 和 B 的最大公约数。本题要求,对于给定的 A 和 B ,
找到对应的 X , Y 和 D 。

输入格式:

输入给出一些行,每行由空格隔开的整数 A 和 B 组成, 0<A,
B<1000000001 。

输出格式:

对于每个输入行,输出一行,由三个用空格隔开的整数 X 、 Y 和 D组成。如果有若干个满足条件的 X 和 Y ,那么就输出 |X |+|Y| 最小的那对。如果还是有若干个 X 和 Y 满足最小准则,则输出 X≤Y 的那一对。

输入样例:

4 6
17 17

输出样例:

-1 1 2
0 1 17

代码长度限制   16 KB

时间限制     400 ms

内存限制     64 MB

思路分析:

直接按照欧里几何拓展的思维来解题~

代码如下:

#include<iostream>
using namespace std;

int Exgcd(int a, int b, int& x, int& y) {
	if (b == 0) {
		x = 1;
		y = 0;
		return a;
	}
	int d = Exgcd(b, a % b, y, x);
	y -= a / b * x;
	return d;
}

int main()
{
	int a, b, x, y;
	while (cin >> a >> b) {
		int temp = Exgcd(a, b, x, y);
		cout << x << " " << y << " " << temp << endl;
	}
	return 0;
}

PS:成功解题=理清思路+一定的技巧~