【拡張ユークリッド】POJ 1061+zoj 2657


http://poj.org/problem?id=1061 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1657両題はそっくりだが、無解時の出力状況が異なるだけで、まず題意が「x+msとy+nsが等価関係を確立し、回数をs」:x+ms≡(y+ns)(mol L)------------------------(x+ms)%L=(y+ns)%L--------(y+ms)-(y+ns)=k*L化簡略化:k*L+(n-L)*s=x-y令a=L,b=n-m,n=x-y得ak+bs= bs=bs=b n;[ここでk,sは未知数であり、ax+by=n Egcd解析:(Egcdはax+by=gcd(a,b)を解くための(a,bは定数))【扩展欧几里德】POJ 1061 + zoj 2657方程式を解く手順:①:d=gcd(a,b)②:n%d!=0であれば、無解③:方程式の両側をdで同時に割ってa'k+b's=n'④:拡張ユークリッドEgcdでa'k+b's=1の解s⑤:得られた[s*n']方程式の1組の解⑥です:最も小さい非負の整数解を得て、型a+a型a【bの型aを求めて、aの型bを求めて、どうして?読者に自分で考えてもらいます】

#include <iostream>
#include <algorithm>
#include <string>
//#include <map>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
//#include <ctime>
#include <ctype.h>
using namespace std;
#define LL long long
#define inf 0x3fffffff

LL gcd (LL a, LL b)
{
	return b ? gcd (b, a%b) : a;
}

void Egcd (LL a, LL b, LL &x, LL &y)
{
	if (b == 0)
	{
		x = 1, y = 0;
		return ;
	}
	Egcd (b, a%b, x, y);
	LL tp = x;
	x = y;
	y = tp - a/b*y;
}

int main()
{
	LL xx, yy, a, b, x, y, L, n, M, N, d;
	while (~scanf ("%lld%lld%lld%lld%lld", &xx, &yy, &M, &N, &L))
	{
		a = L;
		b = N - M;
		n = xx - yy;
		d = gcd (a, b);
		if (n % d != 0)
		{
			puts ("Impossible");
			continue;
		}
		a /= d;
		b /= d;
		n /= d;
		Egcd (a, b, x, y);
		y *= n;
		if (a < 0) a = -a;    //     
		y = (y % a + a) % a;
		printf ("%lld
", y); } return 0; }