본문 바로가기
스터디/정수론

[정수론] 디오판토스 방정식 (Diophantine equation)

by 궁금한 준이 2024. 8. 19.
728x90
반응형

 

디오판토스 방정식 (ax+by=c)

정수를 계수로 갖는 방정식의 정수해를 구하는 문제를 디오판토스 방정식 (또는 부정방정식)이라 한다.

요즘에도 그런지 모르겠는데, 필자가 고등학생일때 수학의 정석에 간단한 경우(상황이 특수한 경우)에 소개되어있다.

정수론에서 보다 일반적인 방법으로 이 방정식을 푸는 방법을 소개한다.

a,b,cZ이고 (적어도 하나는 0이 아니다.) d=gcd(a,b)라 하자. 이 때,
(1) 방정식 ax+by=c의 해가 존재하기 위한 필요충분조건은 dc 이다.
(2) x0,y0ax+by=c의 특수해(particular solution)일 때, 일반해는 다음과 같다.
x=x0+(bd)t,y=y0(ad)t
(단, t는 정수)

 

방정식 3x+6y=18의 경우, (3,6)=3이고 318 이므로 해가 존재한다.

방정식 2x+10y=17의 경우, (2,10)=2이고 217이므로 해가 존재하지 않는다.

 

해의 존재성 증명

ax+by=c has a solutiondc, where d=gcd(a,b)

(i)

ax+by=c의 해가 존재한다고 하자.

d=gcd(a,b)라 하면 a=dr이고 b=ds인 정수 r,s가 존재한다.

c=ax+by=drx+dsy=d(rx+sy) 이므로 dc이다.

(ii)

유클리드 호제법에 의해, ax0+by0=dx0,y0가 존재한다.

dc이므로 c=dt인 정수 t가 존재한다.

따라서 c=dt=a(tx0)+b(ty0)=ax+by

 

일반해(General Solution) 구하기

x,yax+by=c의 general solution이라 하자.

c=ax+by=ax0+by0이므로 a(xx0)=b(y0y)

a=dr,b=ds인 소수 r,s가 존재하므로 r(xx0)=s(y0y)로 쓸 수 있다.

그리고 rs(y0y)이고 gcd(r,s)=1이기 때문에 r(y0y)

따라서 y0y=rt인 정수 t가 존재한다.

정리하면 y=y0rt=y0(ad)t이고 x=x0+(bd)t 이다.

 

예제 1. 

216x+152y=16

유클리드 알고리즘을 이용하여 gcd(216,152)를 구해보면

216=1521+64152=642+2464=242+1624=161+816=82

gcd(216,152)=8이고 816 이므로 해가 존재한다.

216(7)+15210=8이므로 2를 곱해서 특수해 x0=14,y0=20을 찾을 수 있다.

따라서 일반해는 x=14+19t, y=2027t 이다.

※ 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.')​

 

디오판토스 방정식의 확장

이제 n개의 미지수 x1,x2,,xn를 갖는 디오판토스 방정식을 구하는 방법을 알아보자.

a1,a2,,an이 모두 0은 아닌 정수고, d=(a1,a2,,an)이라 하자. 이 때 방정식
a1x1+a2x2++anxn=c
의 해가 존재할 필요충분조건은 dc 이다.

 

일반해를 구하는 방법

d1=(a1,a2)라 하자. 그러면 n1개의 미지수 u,x3,x4,,xn을 갖는 방정식 

(a1λ1+a2λ2)u+a3x3+a4+x4++anxn=c를 푼다.

이렇게 계속 미지수를 줄여가다보면 미지수가 2개인 방정식의 해를 구하는 문제로 귀결된다.

 

예제 2.

21x+14y+12z=4

의 해를 구해보자.

먼저 (21,14,12)=(7,12)=1이고 14이므로 해가 존재한다.

(21,14)=7이므로 위 방정식은 

7u+12z=4,u=3x+2y

이다.

 

7u+12z=4의 특수해는 x0=20,y0=12이므로

u=20+12t, z=127t 이다.

u=3x+2y이므로 3x+2y=20+12t

(3,2)=1이고 1|(20+12t)이므로 해를 갖는다.

한편 (유클리드 알고리즘을 이용하지 않고도 보인다) 31+2(1)=1이므로

3(20+12t)+2(2012t)=20+12t 임을 알 수 있다.

따라서 정수해는

x=20+12t+2s,y=2012t3s,z=127t

이다.

 

BOJ 3955, 캔디 분배, 플레티넘 5

https://www.acmicpc.net/problem/3955

문제를 해석하면 다음과 같다.

  • kx+1=cn을 만족하는 n을 구한다. n이 존재하지 않으면 "IMPOSSIBLE"을 출력한다.
  • k, c, n의 범위는 모두 1이상 109 이하이다.

디오판토스방정식의 조금 전 단계인 베주항등식을 푸는 문제이다.

kx+1=cncn+k(x)=1로 보고, ax+by=1의 형태로 간주하여 푼다.

확장 유클리드 호제법으로 구할 수 있다.

그리고 n의 특수해를 구한 후(n0), 일반해의 범위에서 최솟값을 찾는다. n=n0+kt

이때 k는 항상 양수임이 보장되므로 부등식 n0+kt>0을 만족하는 k의 범위는 k>n0k

정수범위에서는 tmin=n0k 가 된다.

범위 안에 n이 있으면 아무거나 출력하면 되므로 tmaxnmax는 굳이 구할 필요가 없다.

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)
728x90
반응형