https://www.acmicpc.net/problem/11688
문제 설명
세 정수 a, b, L이 주어졌을 때, LCM(a, b, c) = L을 만족하는 가장 작은 c를 찾는 프로그램을 작성하시오. LCM(a, b, c)는 a, b, c의 최소공배수이다.
풀이 과정
- 나의 풀이
① 문제 바라보기
LCM(a,b,c) = L 의 과정에서 a,b,L이 주어졌고, 가장 작은 c를 구하는 것이 문제에서 요구하는 것이다.
기본적으로 최소공배수는 유클리드 호제법을 통해 구할 수 있다.
※ 최소공배수 구하는 법
① 최대공약수 구하는 법
유클리드 호제법을 통해 최대공약수를 쉽게 구할 수 있다.
유클리드 호제법이란 기원전 300년 전에 나온 가장 오래된 알고리즘으로 유명하다.
유클리드 호제법으로 최대공약수를 구하는 방법은 다음과 같다.
○ 두 자연수 a,b에 대하여 a를 b로 나눈 나머지 r에 대해 a와 b의 최대공약수는 b와 r의 최대공약수와 같다. 이를 계속 반복하며 b가 0이 될 때, a값이 바로 최대공약수이다. (재귀와 반복이 느껴진다..!!)
② 최소공배수 구하는 법
입력값인 두 정수 a,b에 대하여 a = x * gcd , b = y * gcd (단, gcd는 a와 b의 최대공약수이고, x와 y는 서로 서로소 관계이다.) 이므로 최소공배수는 a*b//gcd가 된다..!!
② 아이디어 열기
a,b,c의 최소공배수를 구하는 과정에서 a,b,c의 최소공배수는 a,b의 최소공배수와 c 의 최소공배수와 같다.
그리고 가장 작은 c를 구해야하므로.. L 의 약수 중에서 a,b의 최소공배수와 최소공배수를 구했을 때 L이 되는 가장 작은 L의 약수가 c가 될 것이다...!
이를 코드로 구현하면 다음과 같다.
# 11688 최소공배수 찾기
import sys
input = sys.stdin.readline
a,b,L = map(int,input().split())
def gcd_for(a,b) :
while b > 0 :
tmp = a%b
a = b
b = tmp
return a
def lcm(a,b) :
return a*b//gcd_for(a,b)
def get_divisor(n):
n = int(n)
divisors = []
divisors_back = []
for i in range(1, int(n**(1/2)) + 1):
if (n % i == 0):
divisors.append(i)
if (i != (n // i)):
divisors_back.append(n//i)
return divisors + divisors_back[::-1]
divisor_lst = get_divisor(L)
A = lcm(a,b)
result = 0
for i in range(len(divisor_lst)) :
if lcm(A,divisor_lst[i]) == L :
result = divisor_lst[i]
print(result)
break
if result == 0 :
print(-1)
gcd_for 함수를 통해 최대공약수를 구할 수 있고, lcm 함수를 통해 최소공배수를 구할 수 있다.
get_divisor 함수를 통해 약수를 구할 수 있다.
아래의 for문을 통해 c값을 구하여 result에 저장한 뒤 출력한다.
후기
솔직히 약수 구하는게 너무 힘들었다...!!
'Algorithm > math' 카테고리의 다른 글
[백준] 2824 최대공약수 (파이썬 Python) (0) | 2021.08.13 |
---|---|
[백준] 1850 최대공약수 (파이썬 Python) (0) | 2021.08.13 |
[백준] 2609 최대공약수와 최소공배수 (파이썬 Python) (0) | 2021.08.13 |
[백준] 9613 GCD 합 (파이썬 Python) (0) | 2021.08.13 |
[백준] 13241 최소공배수 (파이썬 Python) (0) | 2021.08.13 |