728x90
반응형
문제 살펴보기!!
문제 링크 : https://www.acmicpc.net/problem/4134
반응형
솔루션 살펴보기!!
def is_prime(n):
# n이 2보다 작으면 소수가 아님
if n < 2:
return False
# 2, 7, 61에 대해 나눠떨어지는지 체크 (특정 작은 소수에 대해 직접 확인)
for p in [2, 7, 61]:
if n % p == 0:
return n == p
# n-1 = d * 2^s 형태로 변환
d = n - 1
s = 0
while d % 2 == 0:
d //= 2
s += 1
# 미르만-라빈 소수 판정법 적용
for a in [2, 7, 61]:
if a >= n:
continue
x = pow(a, d, n)
if x == 1 or x == n - 1:
continue
# 제곱을 반복하여 소수 여부를 판정
for _ in range(s - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
def next_prime(n):
# n이 2 이하인 경우 2 반환
if n <= 2:
return 2
# n이 짝수면 다음 홀수부터 검사 시작
if n % 2 == 0:
n += 1
# 홀수 단위로 증가시키면서 소수 여부 판정
while not is_prime(n):
n += 2
return n
def main():
# 입력 처리 및 소수 찾기
T = int(input().strip()) # 테스트 케이스 개수
for _ in range(T):
n = int(input().strip()) # 주어진 수 n
print(next_prime(n)) # n보다 크거나 같은 다음 소수 출력
if __name__ == "__main__":
main()
주요 코드 설명
- is_prime 함수:
- n < 2: 2보다 작은 수는 소수가 아니므로 False 반환.
- [2, 7, 61]: 이 작은 소수로 먼저 나눠서 나눠 떨어지면 소수 여부를 빠르게 판정.
- d와 s 계산: n-1을 d * 2^s 형태로 분해.
- 미르만-라빈 테스트: 소수 판정을 위한 반복 제곱 검사.
- next_prime 함수:
- 입력값이 2 이하일 때는 바로 2 반환.
- 짝수일 경우 다음 홀수부터 소수 여부를 검사.
- while 루프: 소수가 될 때까지 홀수 단위로 증가하면서 is_prime을 통해 검사.
- main 함수:
- 테스트 케이스 개수를 입력받고, 각 테스트 케이스에 대해 next_prime 함수를 호출하여 소수 결과를 출력.
풀이 전략 및 주요 코드 흐름
- 문제 이해 및 요구사항 분석:
- 입력으로 주어진 정수 n보다 크거나 같은 첫 번째 소수를 찾아야 합니다.
- 소수를 찾기 위해 소수 판정 알고리즘과 다음 소수를 찾는 반복 로직을 구현해야 합니다.
- 풀이 전략:
- 소수 판정: 미르만-라빈 소수 판정법을 사용하여 n이 소수인지 판별합니다. 이 알고리즘은 특정 작은 소수([2, 7, 61])를 기반으로 하여, 오차를 최소화하며 소수 판정 속도를 높입니다.
- 다음 소수 찾기: 주어진 n부터 시작하여 홀수 단위로 증가하면서 소수 여부를 검사하여 가장 가까운 소수를 찾습니다.
- 주요 코드 흐름:
- is_prime 함수: 입력된 n이 소수인지 판정합니다.
- 2보다 작은 경우는 소수가 아니라고 판정.
- n이 2, 7, 61 중 하나로 나누어떨어지는지 확인하여 소수 여부를 먼저 빠르게 판별.
- 미르만-라빈 알고리즘을 통해 더 큰 수에 대해 소수 여부를 검증.
- next_prime 함수: 주어진 n보다 크거나 같은 다음 소수를 찾습니다.
- nn이 2 이하이면 바로 2를 반환.
- 홀수 단위로 증가시키면서 is_prime을 사용해 소수 여부를 확인하여 결과를 반환.
- main 함수: 입력을 처리하고 각 테스트 케이스에 대해 next_prime 함수를 호출해 결과를 출력합니다.
- 입력받은 T개의 테스트 케이스에 대해 각각 n을 받아서, 해당 n보다 크거나 같은 소수를 출력합니다.
- is_prime 함수: 입력된 n이 소수인지 판정합니다.
코드 면접시 알아야할 주요 개념
이 코드와 관련된 코드 면접에서 중요하게 다룰 수 있는 개념들은 다음과 같습니다. 이는 소수 판정 문제와 관련된 알고리즘, 최적화 기법, 그리고 일반적인 프로그래밍 개념을 포함합니다:
1. 소수 판정 알고리즘 (Primality Testing)
- 미르만-라빈 소수 판정법 (Miller-Rabin Primality Test):
- 이 알고리즘은 확률적 소수 판정법으로, 특정한 기반 숫자 집합에 대해 높은 확률로 소수를 판정할 수 있습니다.
- 코드에서 사용하는 [2, 7, 61]은 이 알고리즘의 기반 숫자들로, 64비트 정수 범위에서 충분히 정확하게 소수를 판정할 수 있는 값입니다.
- 알고리즘의 핵심은 n-1을 2^s * d 형태로 분해하고, 특정한 조건을 만족하는지 반복적으로 확인하는 것입니다.
- 면접에서 이 알고리즘을 사용하는 이유와 기본적인 원리에 대해 설명할 수 있어야 합니다.
2. 시간 복잡도 분석 (Time Complexity Analysis)
- 소수 판정의 시간 복잡도:
- 미르만-라빈 테스트의 시간 복잡도는 일반적으로 O(klog3n)O(k \log^3 n)로, kk는 테스트 횟수입니다. 이때, k는 코드에서 [2, 7, 61]의 길이로, 고정된 값입니다.
- next_prime 함수에서 소수를 찾기 위해 반복문을 사용하며, 이때 각 수를 소수 판정하는 비용이 누적됩니다.
- 최악의 경우 분석:
- 소수 사이의 간격이 좁으면 빠르게 다음 소수를 찾을 수 있지만, 간격이 넓은 경우 더 많은 수를 탐색해야 합니다. 이 점에 대해 설명할 수 있어야 합니다.
3. 수학적 개념 (Mathematical Concepts)
- 페르마의 소정리와 거듭제곱 모듈 연산 (Modular Exponentiation):
- 소수 판정에 사용되는 기본 원리로, 특정 수 a에 대해 an−1mod n=1a^{n-1} \mod n = 1이 성립하는지를 확인합니다.
- 이 코드에서 pow(a, d, n)를 사용하여 효율적으로 거듭제곱 모듈 연산을 수행합니다.
- 이러한 수학적 배경 지식을 이해하고, 왜 이러한 원리를 소수 판정에 사용하는지 설명할 수 있어야 합니다.
4. 코드 최적화 (Code Optimization)
- 홀수만 검사하는 로직:
- 코드에서 짝수는 소수가 될 수 없으므로, 다음 소수를 찾을 때 n을 2씩 증가시키는 방식으로 짝수를 건너뜁니다.
- 이는 탐색 공간을 절반으로 줄여 성능을 크게 향상시키는 기법입니다.
- 사전 필터링:
- 2, 7, 61과 같은 작은 소수에 대해 먼저 나눠서 체크하는 것은 빠르게 특정 수가 소수인지 판별하는 데 유용합니다.
- 이는 미르만-라빈 테스트를 직접 적용하기 전에 불필요한 연산을 줄일 수 있게 해줍니다.
5. 입출력 최적화 (Input/Output Optimization)
- 입력 처리 방식:
- 입력이 여러 줄로 주어질 때, sys.stdin.read를 사용하면 성능이 좋지만, 코드의 간결성을 위해 input()을 여러 번 사용하는 것도 나쁘지 않습니다.
- 면접에서는 입력 처리 방식을 선택할 때 성능과 간결성 사이의 트레이드오프를 이해하고 설명할 수 있어야 합니다.
6. 반복문과 조건문 사용의 효율성
- 반복문 내 조건 사용:
- for _ in range(s - 1)와 같은 반복문은 소수 판정 과정에서 반복적인 제곱 계산을 수행합니다. 이때, 조기 탈출(break)을 통해 효율성을 높이는 로직이 포함되어 있습니다.
- 면접에서는 이러한 반복문 사용의 이유와 조기 탈출을 통한 효율성 향상을 설명할 수 있어야 합니다.
7. 에지 케이스 (Edge Cases) 처리
- n이 2 이하일 때:
- n이 2보다 작을 때 2를 반환하는 로직은 중요한 에지 케이스 처리입니다.
- 면접에서는 소수 판정 문제에서 흔히 발생하는 에지 케이스, 예를 들어 n이 0, 1, 또는 매우 큰 숫자일 때의 처리 방법을 설명할 수 있어야 합니다.
8. 알고리즘 선택 이유 및 대안 비교
- 미르만-라빈 테스트 vs. 에라토스테네스의 체:
- 면접에서는 특정 문제에 대해 왜 미르만-라빈 소수 판정법을 사용했는지 설명하고, 다른 알고리즘 (예: 에라토스테네스의 체)과의 비교를 할 수 있어야 합니다.
- 에라토스테네스의 체는 많은 수에 대해 소수를 한 번에 찾을 때 유리하지만, 미르만-라빈 테스트는 특정 수 하나의 소수 여부를 확인하는 데 적합합니다.
728x90
반응형
'알고리즘' 카테고리의 다른 글
백준 알고리즘 문제 풀이 가이드: 코딩 면접 대비 완벽 준비-9613 GCD 합 편 (python) (0) | 2024.10.15 |
---|---|
백준 알고리즘 문제 풀이 가이드: 코딩 면접 대비 완벽 준비-21920 서로소 평균 편 (python) (0) | 2024.10.14 |
백준 알고리즘 문제 풀이 가이드: 코딩 면접 대비 완벽 준비-5347 LCM 편 (python) (0) | 2024.10.09 |
백준 알고리즘 문제 풀이 가이드: 코딩 면접 대비 완벽 준비-3584 가장 가까운 공통 조상 편 (python) (0) | 2024.10.08 |
백준 알고리즘 문제 풀이 가이드: 코딩 면접 대비 완벽 준비-1967 트리의 지름 편 (python) (0) | 2024.10.07 |