BOJ1016 제곱 ㄴㄴ수
골드1 | 백준 1016 | Python3 파이썬 풀이
i
)j
는 배수 만들기 용 변수 (i * i * j
가 MAX
보다 작을 때까지 반복)i * i * j
가 인덱스 범위 내이면 방문 체크, 개수 세기(len(a) - count)
문제점
1) 에라토스테네스의 체를 이용하지 않으면 → 시간 초과
2) 에라토스테네스의 체를 이용하고 → 숫자를 담는 리스트를 만들거나, 리스트의 길이를 0부터 MAX까지 하면 메모리 초과
3) 하나의 리스트를 이용해 에라토스테네스의 체를 이용해야 함
4) 방문 체크를 해야 하는데, 인덱스 범위 조정 필요 및 체크 필요 (N ~ M + 1)
→ 범위를 조정하지 않으면 시간 초과
5) C 계열은 int
범위를 벗어나므로 long long
타입 사용
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
# 에라토스테네스의 체 (소수면 True)
a = [True for _ in range(M - N + 1)]
count = 0
i = 1
# 에라토스테네스의 체
while i * i <= M:
i += 1
j = N // (i * i)
while i * i * j <= M:
# i^2의 배수
sq = i * i * j
if sq >= N:
if a[sq - N]:
count += 1
# 소수가 아니므로 체크
a[sq - N] = False
j += 1
print(len(a) - count)
기본 아이디어는 쉬우나 (에라토스네테스의 체 응용)
시간 초과와 메모리 초과를 줄이기 위해, 인덱스 범위를 재조정하는 것이 어려웠음
→ 더 빠르고 메모리 소모가 적은 밀러-라빈 방식 사용해보기