공부/알고리즘

[단계별로 풀어보기][Python 3] 정수론 및 조합론 - 검문(2981)

도리암 2022. 5. 3. 17:17

2981번: 검문 (acmicpc.net)

 

2981번: 검문

트럭을 타고 이동하던 상근이는 경찰의 검문을 받게 되었다. 경찰은 상근이가 운반하던 화물을 하나하나 모두 확인할 것이기 때문에, 검문하는데 엄청나게 오랜 시간이 걸린다. 상근이는 시간

www.acmicpc.net

위 문제를 풀기 위해서는 수학적인 계산이 먼저 필요하다.

수식 도출

각 숫자를 m으로 나눴을 때 나머지가 동일해야 하므로 다음의 식을 세울 수 있다.

위의 식에서 r이 동일하게 나오므로, 각 항목을 빼주면 m을 최대공약수로 가지는 수가 도출된다.

풀이

def gcd(a, b):
    while b != 0:
        r = a % b
        a = b
        b = r
    return a

n = int(input())
num = sorted([int(input()) for _ in range(n)])

re_num = [num[i+1]-num[i] for i in range(n-1)]

g = re_num[0]
for i in range(1, len(re_num)):
    g = gcd(g, re_num[i])


res = set()
for i in range(2, int(g**0.5)+1):
    if g%i == 0:
        res.add(i)
        res.add(g//i)
res.add(g)

print(*sorted(list(res)))

각  수를 num에 저장하고, 뺄셈을 했을 때 양수가 나올 수 있도록 정렬해준다.

re_num에 num의 각 요소의 차이를 저장한뒤 모든 수의 최대공약수를 구해준다.

 

최대공약수를 구했으면 그 최대공약수의 약수를 구한다.

이 때, 수의 범위가 1,000,000,000으로 매우 크므로 제곱근까지만 시도하여 수행 시간을 줄인다.

print(*list)를 하면 리스트의 전체 요소를 대괄호 없이 출력해준다.