문제
https://www.acmicpc.net/problem/1016
풀이
전형적인 에라토스테네스의 체 문제이다. 범위가 1000000000000 ~ 1000001000000 를 가지므로 min부터 max 까지 돌린다면 O(n^2)의 시간이 걸린다. 따라서 좀 더 최적화된 방법이 필요하다.
min 이상인 수 중에 가장 작은 제곱수를 찾고 max 이하까지의 범위를 전부 찾고, 그걸 1 * 1 부터 n * n의 범위까지 전부 돌려 찾으면 시간 안에 찾을 수 있다.
파이썬은 거의 처음과 다름이 없어서 C++처럼 능숙하게 다루지 못한다. 원래 부딪히면서 익히는 본인의 특성상 무작정 코딩하면서 공부했던걸 주석으로 달았다.
# 파이썬은 a = input() b = input() 이런식으로 입력을 넣으면 입력을 넣을 때 '1 10' 과 같이 한줄에 # 입력을 전부 넣지 못한다. 따라서 입력 받을 변수를 map에 넣고 split으로 공백 단위로 잘라서 입력을 # 시켜주면 된다. min, max = map(int, input().split(' ')) # 파이썬은 기본적으로 가변길이의 배열 및 리스트를 가진다. 따라서 고정길이를 가지려면 배열에 초기화 값을 넣고 # 할당하고자 하는 크기를 곱해준다. num = [0] * 1000001 # 제곱ㄴㄴ수는 2이상인 제곱수로 나누어지지 않은 수를 의미하므로 2부터 시작한다. n = 2 while n * n <= max: tmp = n * n n += 1 # 최소값이 n * n으로 나누어지지 않은 제곱ㄴㄴ수이면 시작점을 min으로 해준다. if min % tmp == 0: start = min # 그게 아니면 min에 n * n으로 나눈 나머지를 빼서 n * n의 배수로 만들어주고 빼주게 되면 min보다 작아지므로 n * n을 다시 더해준다. else: start = min - (min % tmp) + tmp m = 0 # n * n의 배수꼴로 나오면 max 이하까지 n * n을 더하면서 체크해준다 while start + tmp * m <= max: #print(start * m - min) num[start + tmp * m - min] = 1 m += 1 cnt = 0 for i in range(0, max - min + 1): #print(i + 1, num[i]) if num[i] == 1: cnt += 1 print(max - min + 1 - cnt)
댓글
댓글 쓰기