扩展欧几里得——POJ1061

题目链接:http://poj.org/problem?id=1061

一个结论(摘自紫皮书):

设a, b, c为任意整数。

若方程ax + by = c 的一组整数解为(x0,y0),则它的任意整数解都可以写成(x0+kb', y0-ka')

其中a' = a/gcd(a, b); b' = b/gcd(a, b);k取任意整数


设d = gcd(a, b)

对当前方程ax +by = d而言

下一步:by1 + (a - kb)x1 = d

即 ax1 + b(y1 - kx1) = d

则 y = y1 - kx1

扩展欧几里得算法:

void gcd(long long a, long long b, long long &d, long long &x, long long &y)
{
	if(!b)
	{
		d = a;
		x = 1;
		y = 0;
	}
	else
	{
		gcd(b, a%b, d, y, x);
		y -= x*(a/b);
	}
}

题目代码:

#include<iostream>
#include<cstdio>
using namespace std;
void gcd(long long a, long long b, long long &d, long long &x, long long &y)
{
	if(!b)
	{
		d = a;
		x = 1;
		y = 0;
	}
	else
	{
		gcd(b, a%b, d, y, x);
		y -= x*(a/b);
	}
}
int main()
{
	long long x, y, m, n, l, k, t;
	while(scanf("%lld %lld %lld %lld %lld", &x, &y, &m, &n, &l) != EOF)
	{
		long long ans = n-m;
		long long a = n-m;
		gcd(a, l, ans, t, k);
		a /= ans;
		l /= ans;
		if((x-y) % ans == 0)
		{
			long long z = (x-y)/ans;
			t = ((z*t)%l + l)%l;
			if(t == 0)
				t += l;
		}
		else
		{
			cout<<"Impossible"<<endl;
			continue;
		}
		cout<<t<<endl;
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/swin16/article/details/79219362
今日推荐