
디오판토스 방정식 ( )
정수를 계수로 갖는 방정식의 정수해를 구하는 문제를 디오판토스 방정식 (또는 부정방정식)이라 한다.
요즘에도 그런지 모르겠는데, 필자가 고등학생일때 수학의 정석에 간단한 경우(상황이 특수한 경우)에 소개되어있다.
정수론에서 보다 일반적인 방법으로 이 방정식을 푸는 방법을 소개한다.
이고 (적어도 하나는 이 아니다.) 라 하자. 이 때,
(1) 방정식의 해가 존재하기 위한 필요충분조건은 이다.
(2)가 의 특수해(particular solution)일 때, 일반해는 다음과 같다.
(단,는 정수)
방정식
방정식
해의 존재성 증명
(i)
(ii)
유클리드 호제법에 의해,
따라서
일반해(General Solution) 구하기
그리고
따라서
정리하면
예제 1.
유클리드 알고리즘을 이용하여
즉
따라서 일반해는
※ particular solution을 유클리드 알고리즘을 이용하지 않아도 된다. 그러나 직관이나 운에 의존하지 않고 특수해를 찾을 수 있다.
Python Code
def ext_gcd(a, b):
x0, x1, y0, y1 = 1, 0, 0, 1
while b != 0:
q = a // b
a, b = b, a % b
x0, x1 = x1, x0 - q * x1
y0, y1 = y1, y0 - q * y1
return a, x0, y0
a = 216
b = 152
c = 16
print(f'{a}x + {b}y = {c}')
d, x0, y0 = ext_gcd(a, b)
if c % d == 0:
x0 *= c // d
y0 *= c // d
print(f'Particular Solution: x = {x0}, y = {y0}')
print(f'General Solution: x = {x0} + {b // d}t, y = {y0} - {a // d}t')
else:
print('No solution.')
디오판토스 방정식의 확장
이제
이 모두 은 아닌 정수고, 이라 하자. 이 때 방정식
의 해가 존재할 필요충분조건은이다.
일반해를 구하는 방법
이렇게 계속 미지수를 줄여가다보면 미지수가
예제 2.
의 해를 구해보자.
먼저
이다.
한편 (유클리드 알고리즘을 이용하지 않고도 보인다)
따라서 정수해는
이다.
BOJ 3955, 캔디 분배, 플레티넘 5
https://www.acmicpc.net/problem/3955
문제를 해석하면 다음과 같다.
을 만족하는 을 구한다. 이 존재하지 않으면 "IMPOSSIBLE"을 출력한다. , , 의 범위는 모두 이상 이하이다.
디오판토스방정식의 조금 전 단계인 베주항등식을 푸는 문제이다.
확장 유클리드 호제법으로 구할 수 있다.
그리고
이때
정수범위에서는
범위 안에
import sys
#sys.stdin = open('input.txt', 'r')
#sys.setrecursionlimit(10 ** 7)
input = lambda: sys.stdin.readline().rstrip()
MIN = 0
MAX = 10 ** 9
def ext_gcd(a, b):
x0, x1, y0, y1 = 1, 0, 0, 1
while b != 0:
q = a // b
a, b = b, a % b
x0, x1 = x1, x0 - q * x1
y0, y1 = y1, y0 - q * y1
return a, x0, y0
def solve(K, C):
# C * N + K * (-X) = 1
if C == 1:
if K + 1 <= MAX:
return K + 1
else:
return 'IMPOSSIBLE'
if K == 1:
return 1
# C * N + K * (-X) = 1
d, n0, x0 = ext_gcd(C, K)
#print(d, n0, x0)
if d != 1:
return 'IMPOSSIBLE'
t_min = (-n0 + K - 1) // K
n_min = n0 + K * t_min
#t_max = (10 ** 9 - n0 - 1) // K
#n_max = n0 + K * t_max
#print(n_min, n_max)
if n_min > MAX:
return 'IMPOSSIBLE'
else:
return n_min
T = int(input())
LOWER = 0
UPPER = 10 ** 9
for _ in range(T):
K, C = map(int, input().split())
ans = solve(K, C)
print(ans)
'스터디 > 정수론' 카테고리의 다른 글
[정수론] 소수와 관련된 알고리즘 (소수 판정, 에라토스테네스의 체, 오일러 피 함수) (0) | 2024.08.11 |
---|---|
[정수론] 약수, 배수, 최대공약수, 최소공배수와 관련된 알고리즘 (0) | 2024.08.10 |
[정수론] 오일러의 정리, 페르마의 소정리, 중국인의 나머지 정리, 윌슨의 정리 (0) | 2024.08.06 |