poj 1061 개구리 의 데이트 - 유클리드 확장 알고리즘
(x+m*s)-(y+n*s)=k*l(k=0,1,2....)
살짝 변형 시 키 기:
(n-m)*s+k*l=x-y
n - m = a, k = b, x - y = d, 즉
a*s+b*l=c
사실은 유클리드 알고리즘 을 확장 하 는 것 입 니 다. - 부정 방정식 을 푸 는 것 입 니 다. 。
상식 에 정수 해 가 존재 한다 면 두 개 구 리 는 만 날 수 있 고 그렇지 않 으 면 안 된다.
대 원 방정식 a * t + b * p = d, 우 리 는 t, p 를 요구 합 니 다.
분명히 c 는 gcd (a, b) 의 배수 일 것 이다. 그렇지 않 으 면 양쪽 을 동시에 gcd (a, b) 로 나 누 면 오른쪽 은 소수 가 되 고 비합법적 이다.
따라서 d / gcd (a, b) 는 반드시 정수 이다.
c=gcd(a,b);
그래서 우 리 는 유클리드 확장 원 리 를 통 해 구 해 야 한다. a * t0 + b * p0 =gcd(a,b);
t0 을 얻 은 후에 t0 * (d / c) 이 가장 작은 해 입 니 다.(gcd (a, b) * d / c = d 때문에)
즉 방정식: a * t0 *(d / c) + b * p0 * (d / c) = d; 그런데 t0 이 마이너스 일 수도 있어 요.
우 리 는 약간의 변 화 를 할 수 있다.
a * ( t0 *(d / c) + b*n) + b * (p0 * (d / c) – a*n) = d; (n 은 자연수) (+a*b*n-a*b*n)
그래서 t =
t0*(d/c)%b ,while( t< 0 ){ t+= b; }
그렇다면 어떻게 유클리드 확장 원 리 를 통 해 t0 을 구 합 니까?
바로 a * x + b * t = gcd (a, b) 와 같은 방정식 에 대해 a > b 를 가정 하면 두 가지 상황 이 있다.
상황 1. b = 0 이면 방정식 은 x = 1; y = 0 으로 해 제 됩 니 다.
상황 2 、 만약 ab! = 0,
a * x + b * y = gcd (a, b) 를 설정 합 니 다. (1)
1. 그리고 유클리드 원리 에서 gcd 를 구 할 때 우 리 는 gcd (a, b) = gcd (b, a% b) 가 있다 는 것 을 알 고 있다.
그럼 지금 (1) 중의 a, b 를 b, a% b 로 교체 하여 얻 을 수 있 습 니 다.
b * x0 + (a % b) * y0 = gcd( b, a % b); (2)
연립 2 식,
a * x + b * y = b * x0 + (a % b) * y0
= b * x0 + (a – a / b * b) * y0
= a * y0 + ( x0 – a / b * y0 ) * b
그래서 x = y0, y = x0 – a / b * y0;
한편, y0, x0 은 y1, x1 을 통 해 구 해 야 한다. 즉, gcd 를 구 하 는 것 처럼 계속 돌아 가 마지막 a% b = = 0 까지
이때 의 x0 = 1; y = 0; (상황 1 에 해당)
다음은 유클리드 확장 프로그램 입 니 다.
void extend_euild(__int64 a, __int64 b)
{
if (b==0)
{
t=1;
p=0;
}
else
{
extend_euild(b,a%b);
__int64 tmp=t;
t=p;
p=tmp-a/b*p;
}
}
다음은 ac 코드:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
__int64 gcdc(__int64 a,__int64 b){
if(b==0)
return a;
return gcdc(b,a%b);
}
__int64 t,p,c;
void extend_euild(__int64 a, __int64 b)
{
if (b==0)
{
t=1;
p=0;
}
else
{
extend_euild(b,a%b);
__int64 tmp=t;
t=p;
p=tmp-a/b*p;
}
}
int main()
{
__int64 x,y,n,m,l;
scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&l);
if (m==n){
cout<<"Impossible"<<endl;
return 0;
}
__int64 a=n-m;
__int64 b=l;
__int64 d=x-y;
__int64 gcd=gcdc(a,b);
if (d%gcd)
{
printf("Impossible
");
return 0;
}
extend_euild( a, b );
t*= d/gcd ;
while( t< 0 )
{
t+= b;
}
printf( "%I64d
", t%b );
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.