[확장 유클리드 호제법의 원리 이해하기]
ex) 5x + 9y = 2
시간 제한 1초, 골드 I, 백준 21568번
A, B, C가 주어졌을 때, Ax+By=C를 만족하는 (x, y)중에서 다음을 만족하는 것을 아무거나 찾아보자.
- x, y는 정수
- -1,000,000,000 ≤ x, y ≤ 1,000,000,000
- 1,000,000 ≤ A, B, C ≤ 1,000,000
- A, B ≠ 0
첫째 줄에 정수 A, B, C가 주어진다.
1 2 3 # A B C
Ax+By=C를 만족하는 x, y를 공백으로 구분해 출력한다. 문제의 조건을 만족하는 (x, y)가 존재하지 않는 경우에는 -1을 출력한다.
3 0
a(1번째 수) b(2번째 수) c(3번째 수)
# 최대 공약수 gcd() 함수 구현
gcd(a, b):
if b가 0이면:
a가 최대 공약수
else:
gcd(작은 수, 큰 수 % 작은 수) # 재귀 함수 형태로 구현
# 유클리드 호제법 함수 구현
Execute(a, b):
if b == 0: 재귀 함수를 중단하고, x, y를 각각 1, 0으로 설정하여 return
q(a를 b로 나눈 몫)
Execute(b, a % b) # 재귀 함수
x = y', y = x' - y' * 몫을 계산하는 역산 로직 구현
# 재귀에서 빠져나오는 영역에서 실행하면 자연스럽게 역순이 됨
계산된 x y return
최대 공약수 = gcd(a, b)
if c가 최대 공약수의 배수가 아니면:
-1 출력
else:
나머지(b)가 0이 될 때까지 재귀 함수를 호출하는 유클리드 호제법 함수 호출
결괏값에 c/최대 공약수의 값을 곱한 후 해당 값을 출력
a, b, c = map(int, input().split())
def gcd(a, b):
if b == 0:
return a
else:
return gcd(b, a % b)
def Execute(a, b):
ret = [0] * 2
if b == 0:
ret[0] = 1
ret[1] = 0
return ret
q = a // b
v = Execute(b, a % b) # 재귀 형태로 유클리드 호제법 수행
ret[0] = v[1] # 역순으로 올라오면서 x, y를 계산하는 로직
ret[1] = v[0] - v[1] * q
return ret
mgcd = gcd(a, b)
if c % mgcd != 0:
print(-1)
else:
mok = int(c / mgcd)
ret = Execute(a, b)
print(ret[0] * mok, end=' ')
print(ret[1] * mok)