목차

gcd와 set

ps
링크acmicpc.net/…
출처BOJ
문제 번호33837
문제명gcd와 set
레벨골드 3
분류

정수론

시간복잡도O(n+mlogm)
인풋사이즈n<=10^6, m<=5000
사용한 언어Python 3.13
제출기록137016KB / 272ms
최고기록272ms
해결날짜2025/05/15

풀이

코드

코드 1 - O(n^2logn)

"""Solution code for "BOJ 33837. gcd와 set".

- Problem link: https://www.acmicpc.net/problem/33837
- Solution link: http://www.teferi.net/ps/problems/boj/33837

Tags: [math]
"""

import math


def main():
    N = int(input())
    A = [int(x) for x in input().split()]

    a_set = set(A)
    if len(a_set) == 1:
        print(A[0] if N == 1 else A[0] * 2)
        return

    answer = 0
    for i in range(1, max(A) + 1):
        val = i + math.gcd(*(a_i for a_i in a_set if a_i % i != 0))
        answer = max(val, answer)

    print(answer)


if __name__ == '__main__':
    main()

코드 2 - O(n^2logn)

"""Solution code for "BOJ 33837. gcd와 set".

- Problem link: https://www.acmicpc.net/problem/33837
- Solution link: http://www.teferi.net/ps/problems/boj/33837

Tags: [math]
"""

import math
import itertools


def main():
    N = int(input())
    A = [int(x) for x in input().split()]

    size = max(A) + 1
    elem_counter = [0] * size
    for a_i in A:
        elem_counter[a_i] += 1

    if elem_counter[A[0]] == N:
        print(A[0] if N == 1 else A[0] * 2)
        return

    factor_count = [0] * size
    for i in range(1, size):
        factor_count[i] = sum(elem_counter[i:size:i])

    answer = 0
    for i, j in itertools.combinations(range(1, size), 2):
        count = factor_count[i] + factor_count[j]
        if (lcm := math.lcm(i, j)) < size:
            count -= factor_count[lcm]
        if count == N:
            answer = max(answer, i + j)

    print(answer)


if __name__ == '__main__':
    main()

코드 3 - O(nlogn)

"""Solution code for "BOJ 33837. gcd와 set".

- Problem link: https://www.acmicpc.net/problem/33837
- Solution link: http://www.teferi.net/ps/problems/boj/33837

Tags: [math]
"""

import math


def main():
    N = int(input())
    A = [int(x) for x in input().split()]

    a_set = set(A)
    if len(a_set) == 1:
        print(A[0] if N == 1 else A[0] * 2)
        return

    max_elem = max(a_set)
    a_set.discard(max_elem)
    sec_max_elem = max(a_set)
    a_set.discard(sec_max_elem)

    g = math.gcd(*a_set)
    s1 = max_elem + math.gcd(sec_max_elem, g)
    s2 = sec_max_elem + math.gcd(max_elem, g)

    print(max(s1, s2))


if __name__ == '__main__':
    main()