辗转相除法(gcd、exgcd)

欧几里得算法

用于求两个数的最大公约数。复杂度在 O ( l o g ( m a x ( a , b ) ) ) O(log(max(a,b))) 以内。

#include <cstdio>
#include <iostream>
using namespace std;

int gcd(int a, int b)
{
	if (b == 0) return a;
	return gcd(b, a % b);
}

int main(void)
{
	int a, b;
	cin >> a >> b;
	cout << gcd(a, b) << endl; 
	return 0;
}

求n个数的最大公约数

#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e5 + 5;

int arr[N];

int gcd(int a, int b)
{
	if (b == 0) return a;
	return gcd(b, a % b);
}

int main(void)
{
	int n, a, b, ans;
	cin >> n;
	for (int i = 0; i < n; i++){
		cin >> arr[i];
	}
	ans = arr[0];
	for (int i = 0; i < n - 1; i++){
		ans = gcd(ans, arr[i + 1]);
	}
	cout << ans << endl; 
	return 0;
}

扩展欧几里德算法

常用于求 a x + b y = g c d ( a , b ) ax + by=gcd(a,b) 的一组可行解。返回值为 g c d ( a , b ) gcd(a,b) ,并计算出了 x x y y

#include <cstdio>
#include <iostream>
using namespace std;

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

int main(void)
{
	int a, b, x, y;
	cin >> a >> b;
	cout << exgcd(a, b, x, y) << endl;
	cout << x << " " << y << endl;
	return 0;
}

对于int& x

说明这是传递给这个参数的实参的引用
对这个形参修改 就会对实参修改
是一种传址操作

发布了162 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43772166/article/details/103224340