1. 문제 설명
수빈이가 세상에서 가장 좋아하는 것은 소수이고, 취미는 소수를 가지고 노는 것이다.
요즘 수빈이가 가장 관심있어 하는 소수는 7331이다.
7331은 소수인데, 신기하게도 733도 소수이고, 73도 소수이고, 7도 소수이다.
즉, 왼쪽부터 1자리, 2자리, 3자리, 4자리 수 모두 소수이다!
수빈이는 이런 숫자를 신기한 소수라고 이름 붙였다.
수빈이는 N자리의 숫자 중에서 어떤 수들이 신기한 소수인지 궁금해졌다.
N이 주어졌을 때, 수빈이를 위해 N자리 신기한 소수를 모두 찾아보자.
입력
첫째 줄에 N(1 ≤ N ≤ 8)이 주어진다.
출력
N자리 수 중에서 신기한 소수를 오름차순으로 정렬해서 한 줄에 하나씩 출력한다.
2. 풀이 전 계획과 생각
입력
- N → 자리수
구하고자 하는 바
N자리 수 중에서 신기한 소수를 오름차순으로 정렬
필요한 함수
모든 자리수마다 숫자를 배치하여 신기한 배수인지 확인하자.
- 숫자 배치 O(10^N) ⇒ O(10^8)이다. (가지치기 함으로 더 줄어들 것이다.)
- 종료 조건
- N자리 수까지 채웠다면 종료한다.
- 만약에 중간에 소수가 아니면 탐색을 중단한다.
- 자리수마다 1-9의 숫자를 배치하고 소수인지 확인한다.
- 종료 조건
- 소수인지 확인
3. 풀이 - 백트레킹
import math
def is_prime_number(x):
if x <= 1:
return False
for i in range(2, int(math.sqrt(x)) + 1):
if x % i == 0:
return False
return True
def go(current_digit):
global current_number
if current_digit == N + 1:
if len(current_number) == N:
answer.append(int(current_number))
return
if not len(current_number) == 0 and not is_prime_number(int(current_number)):
return
for num in range(1, 10):
if current_digit == N:
if num == 0:
continue
current_number = current_number + str(num)
go(current_digit + 1)
current_number = current_number[:-1]
answer = []
N = int(input())
current_number = ''
go(1)
answer.sort()
for element in answer:
print(element)
문제점
마지막 부분에 소수인지 아닌지 확인해주지 않고 종료해주어서 소수가 아닌 경우도 들어가게 되었다.
가지치기 조건이 종료 조건보다 먼저 앞서 있어야 한다.
4. 2차 풀이 - 백트레킹
import math
def is_prime_number(x):
if x <= 1:
return False
for i in range(2, int(math.sqrt(x)) + 1):
if x % i == 0:
return False
return True
def go(current_digit):
global current_number
if not len(current_number) == 0 and not is_prime_number(int(current_number)):
return
if current_digit == N + 1:
if len(current_number) == N:
answer.append(int(current_number))
return
for num in range(1, 10):
if current_digit == N:
if num == 0:
continue
current_number = current_number + str(num)
go(current_digit + 1)
current_number = current_number[:-1]
answer = []
N = int(input())
current_number = ''
go(1)
answer.sort()
for element in answer:
print(element)
5. 다른 풀이 - 백트레킹, 소수의 특징
시작점을 소수로 두어 시작하고 (2, 3, 5, 7)
짝수가 되면 소수가 아니니, 홀수를 다음 숫자에 추가해주자.
import math
def is_prime_number(x):
if x <= 1:
return False
for i in range(2, int(math.sqrt(x)) + 1):
if x % i == 0:
return False
return True
def go(current_number):
if not is_prime_number(int(current_number)):
return
if len(current_number) == N:
answer.append(int(current_number))
return
for num in odd_number:
current_number = current_number + num
go(current_number)
current_number = current_number[:-1]
answer = []
N = int(input())
start = ['2', '3', '5', '7']
odd_number = ['1', '3', '5', '7', '9']
for element in start:
go(element)
answer.sort()
for element in answer:
print(element)
6. 풀이 후 알게된 개념과 소감
- 종료 조건, 가지치기 조건의 순서를 잘 확인해주자.
'Problem Solving' 카테고리의 다른 글
[프로그래머스] 메뉴 리뉴얼 (2021 KAKAO BLIND) / python (0) | 2022.06.03 |
---|---|
[백준] 16197 : 두 동전 / python (0) | 2022.05.24 |
[백준] 16236 : 아기 상어 (삼성 SW 역량 테스트) / python (0) | 2022.05.15 |
[프로그래머스] 합승 택시 요금 (2021 KAKAO BLIND) / python (0) | 2022.05.13 |
[백준] 3584 : 가장 가까운 공통 조상 / python (0) | 2022.05.09 |