728x90
https://www.acmicpc.net/problem/2023
소수판정 + 백트래킹 / DP 문제입니다.
우리는 한 자리 소수가 2, 3, 5, 7 이라는 것을 알고있습니다.
그렇다면 두 자리 신기한 소수는 2, 3, 5, 7 로 시작할 것을 알고 있고 그 수들만 소수인지 판정하면 됩니다.
그런 식으로 N 자리 신기한 소수는 N-1 자리 신기한 소수로 시작하므로 점차적으로 자릿수를 늘려가며 탐색하면 됩니다.
소수를 판정할 때 모든 수로 나누어가며 판정하는 것은 비효율적이고 에라토스테네스의 체 알고리즘을 통해 최적화를 할 수 있습니다.
N 자리 신기한 소수를 찾을 때 N-1 자리 소수를 보고 탐색할 필요가 없는 수를 가지치기할 수 있으므로 백트래킹 알고리즘이라고 할 수 있고, N 자리 소수를 N-1, ... , 1 자리의 소수를 찾는 문제로 나누어 해결할 수 있으므로 DP 문제라고 할 수 있겠습니다.
import sys
input = sys.stdin.readline
# 소수 판별
def is_prime(num):
# 0, 1 이면 False
if num in [0, 1]:
return False
# 소수 판별 리스트
is_primes = [False, False] + [True for _ in range(int(pow(num, 1/2))-1)]
# 순회
for i in range(2, len(is_primes)):
# 현재 수가 소수가 아니면 패스
if not is_primes[i]:
continue
# 현재 수로 수가 나누어 떨어지면 소수가 아님
if not num % i:
return False
# 아니면 소수 판별 리스트 업데이트
for j in range(2*i, len(is_primes), i):
is_primes[j] = False
# 모두 통과하면 소수
return True
def solution(N):
# 신기한 소수 / amazing_primes[i] = [i 자릿수의 신기한 소수들]
amazing_primes = [['']] + [[] for _ in range(N)]
## i-1 자리의 신기한 소수에 수를 붙여 소수면 추가
# 순회
for i in range(1, len(amazing_primes)):
# i-1 자리의 신기한 소수
for before_num in amazing_primes[i-1]:
# 수 붙이기
for num in range(10):
# 소수 판정을 할 수
now_num = int(before_num + str(num))
# 소수 판정
if is_prime(now_num):
# 신기한 소수 추가
amazing_primes[i].append(str(now_num))
for amazing_prime in amazing_primes[N]:
print(amazing_prime)
# 입력
N = int(input().strip())
solution(N)
728x90
'Coding Test > BaekJoon_Python' 카테고리의 다른 글
백준 1456 <거의 소수> Python (0) | 2024.11.19 |
---|---|
백준 10423 <전기가 부족해> Python (1) | 2024.11.18 |
백준 4179 <불!> Python (1) | 2024.11.17 |
백준 7662 <이주 우선순위 큐> Python (0) | 2024.11.16 |
백준 14284 <간선 이어가기 2> Python (1) | 2024.11.15 |