2981 검문
2021. 12. 13. 23:24
문제 해결을 위한 수학적 알고리즘 2개
1. 유클리드 호제법으로 최대 공약수를 구한다.
2. 약수들을 효율적으로 찾아야 한다. -> 시간초과의 주 원인
우선 입력된 숫자들을 정렬하고, 가장 작은 값을 뺐다.
그러면 최대 공약수를 구할 수 있는 숫자들의 모습이 보인다.
유클리드 호제법을 사용하여 최대 공약수를 구한다.
# 최대공약수 구하는 함수
def get_gcd(a, b):
if b == 0:
return a
c = a % b
return get_gcd(b, c)
이제 최대 공약수의 약수들을 구해야하는데, 1부터 for문으로 세었다가 시간초과를 맞았다.
숫자가 9999990 999999891 이런식이면 엄청 오래걸린다.
그렇다고 숫자들의 가장 작은 수부터 구하는 것도 이상하고.. 그래서 결국 검색했다.
약수들을 효율적으로 찾는 방법은 이미 찾은 약수의 짝을 방문해서 구하지 않는 것이다.
https://inuplace.tistory.com/459
[알고리즘 연습] 약수 구하기 효율화 (by Python)
약수 효율적으로 구하기 1 이상의 자연수 n을 받았을 때 해당 수의 약수들을 구하라. 약수들은 리스트 형태로 숫자 크기 순서대로 출력하라. 단순 풀이 def get_divisor(n): n = int(n) divisors = [] for i in ra
inuplace.tistory.com
# get answers - 최대 공약수의 약수들 저장하기
def get_divisor(n):
divisors = []
divisors_back = []
for i in range(1, int(n ** (1/2)) + 1):
if n % i == 0:
if i != 1:
divisors.append(i)
if i != n // i:
divisors_back.append(n // i)
return divisors + divisors_back[::-1]
제출 코드
import sys
N = int(sys.stdin.readline().rstrip())
numbers = []
# 입력 받고
for _ in range(N):
numbers.append(int(sys.stdin.readline().rstrip()))
numbers.sort()
min_num = numbers[0]
# 모든 수에서 가장 작은 수 만큼을 뺀다.
for i in range(N):
numbers[i] -= min_num
# 최대공약수 구하는 함수
def get_gcd(a, b):
if b == 0:
return a
c = a % b
return get_gcd(b, c)
gcd = 0
for i in range(N-1):
gcd = get_gcd(gcd, numbers[i + 1])
# get answers - 최대 공약수의 약수들 저장하기
def get_divisor(n):
divisors = []
divisors_back = []
for i in range(1, int(n ** (1/2)) + 1):
if n % i == 0:
if i != 1:
divisors.append(i)
if i != n // i:
divisors_back.append(n // i)
return divisors + divisors_back[::-1]
answers = get_divisor(gcd)
print(' '.join(map(str, answers)))
'Dev > 알고리즘' 카테고리의 다른 글
소프티어 나무 수확 Python 풀이 (1) | 2024.02.02 |
---|---|
1707 이분그래프 파이썬 (0) | 2021.12.14 |
백준 2839 설탕배달 파이썬 (0) | 2021.11.03 |
백준 10250 ACM호텔, 2775_부녀회장이 될테야 파이썬 (0) | 2021.11.03 |
백준 1193_분수찾기 파이썬 (0) | 2021.11.01 |