백준 4948, 소수 구하기 (에라토스테네스의 체)

    문제

    https://www.acmicpc.net/problem/4948

     

    4948번: 베르트랑 공준

    베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다. 이 명제는 조제프 베르트랑이 1845년에 추측했고, 파프누티 체비쇼

    www.acmicpc.net

    첫 번째 풀이

    def isPrime(n):
        if n==1:
            return False
        for i in range(2,int(n**0.5)+1):
            if n%i==0:
                return False
        return True
    
    
    while True:
        n=int(input())
        primelist=[]
        if n==0:
            break
        else:
            for i in range(n,2*n+1):
                if isPrime(i):
                    primelist.append(i)
        print(len(primelist))

    첫 번째 풀이이다 예전에 풀었던 소수 판별을 이용하여 소수인지 판별하는 isPrime 함수를 이용하여 n부터 2*n+1까지의 수를 각각 isPrime함수를 적용시켜 소수라면 primelist에 넣는 방식을 사용했지만 그렇게 하게 되면 시간초과가 발생하는 문제가 생겼다.

    isPrime을 사용하는 방식은 한 개의 소수를 구할 때는 괜찮은 방식이지만 범위의 모든 소수를 구할 때는 효율적인 방식이 아니기 때문에 에라토스테네스가 제안한 소수를 구하는 방식을 사용하면 좀 더 효율적으로 소수를 판별 할 수 있다.

    따라서 두 번째는 에라토스테네스의 체를 이용하여 풀이하였다.

     

    두 번째 풀이

    max=123456*2
    primes = [False,False] + [True]*(max-1)
    
    for i in range(2,max+1):
        if primes[i]:
            for j in range(2*i,max+1,i):
                primes[j]=False
    
    while True:
        n=int(input())
        count=0
        if n==0:
            break
        else:
            for i in range(n+1,2*n+1):
                if primes[i]==True:
                    count+=1
        print(count)

    여기서 에라토스테네스의 체란

    범위에서 합성수를 지우는 방식으로 소수를 찾는 방식이다.

    1. 1은 제거 2. 지워지지 않은 수 중 제일 작은 2를 소수로 채택하고, 나머지 2의 배수를 모두 지운다. 3. 지워지지 않은 수 중 제일 작은 3을 소수로 채택하고, 나머지 3의 배수를 모두 지운다. 4. 지워지지 않은 수 중 제일 작은 5를 소수로 채택하고, 나머지 5의 배수를 모두 지운다. 5. (반복)

    따라서 이를 파이썬 코드로 표현하면면

    max=123456*2
    primes = [False,False] + [True]*(max-1)
    
    for i in range(2,max+1):
        if primes[i]:
            for j in range(2*i,max+1,i):
                primes[j]=False

    처럼 되게 된다. 이렇게 코드로 표현하게 되면 primes에는 0부터 246912까지의 값이 소수인지 아닌지를 판별할 수 있는 도구로 사용할 수 있다.

     

    '알고리즘 공부' 카테고리의 다른 글

    백준 9020번, filter와 lambda  (0) 2023.01.02
    시간복잡도 구하기  (0) 2022.12.31
    백준 2775번, 리스트의 값 복사  (0) 2022.12.28
    백준 1157번, dictionary 활용, count함수  (2) 2022.12.27
    백준 1316번 (미해결)  (0) 2022.12.08

    댓글