junyub2   1년 전

m부터 M까지의 숫자를 lst에 넣고, M이하의 모든 완전제곱수를 check에 만들어줬습니다.

check에 해당하는 숫자들중 작은수를 pop해서 p로 저장을 하고,

lst 중에서 p의 배수에 해당하는 숫자들을 제거해줬습니다.

와중에 시간을 줄이기 위해 p보다 크거나 같은 경우에만 동작하도록 했습니다.

그럼에도 시간초과가 나서 한번 아이디어를 얻어보고자 올려봅니다.

import sys
m, M = map(int, sys.stdin.readline().split())
lst = [int(x) for x in range(m, M+1)]
check = [int(x**2) for x in range(2, int(M**(0.5)+1))]

print(lst)
print(check)

def func():
    while check:
        p = check.pop(0) # 한번 확인해본 p는 다시 확인하지 않기 위해 pop을 해줬습니다.
        for i in lst:
            if i % p == 0 and i >= p: # i에 해당하는 숫자가 p의 배수이면서 p이상일때
                lst.remove(i) # lst에서 해당 숫자들을 제거해줬습니다.
    return len(lst)

print(func())

wjh5597486   1년 전

다른 분들 풀이에 도움 되시길. 

시간 초과 나시는 분들은 기본적으로 에라토스네스의 체를 이용하여야 합니다.

해당 알고리즘을 모르시면 찾아보셔야 할거구요.

대충 설명하자면 에라토스네스의 체는 나누는 수의 중복을 피하는 방식으로 소수를 판정합니다.

100이 소수인지 판별하려면 2:sqrt(100)+1 까지의 자연수를 나누었을때 나머지가 0인 경우가 있으면 소수가 아닙니다.

하지만 2 3 4 5 6 7 8 9 10 을 보면 2를 나누는 행위와 4, 6, 8, 10 을 나누는 행위는 결과적으로 동일합니다. 

[2,3,5,7] 만 가지고 나누어보면 된다는 뜻입니다. 리스트에서 2의 배수 3의 배수 5의 배수 7의 배수를 제거해주는 과정이 필요합니다.


해당 문제에서도

n^2 : [4, 9, 16, 25, 36, 49, ...] 리스트를 만드셨을 겁니다. 여기서도 4를 보면 4의 배수 16, 36이 존재합니다. 이러한 항목들이 연산 시간을 늦추게 됩니다. 

해당 리스트에서 중복을 지우는 문제입니다.


난이도 골드1로 되있는데. 에라토스네스의 체 알고리즘을 한번 꼬아놓은 것이라.

골드 4 정도면 충분하지 않나 싶긴하네요..

junyub2   1년 전

감사합니다 !! 

너무 한가지 생각에만 빠져서 4 16 36 등 작은수로 나누어지는 경우를 생각을 못했네요

댓글을 작성하려면 로그인해야 합니다.