알고리즘

[파이썬] 단계별 백준 문제 풀기 - 4948 기본수학2 (베르트랑 공준)

햄❤️ 2021. 3. 13. 11:40
반응형

문제링크

 

4948번: 베르트랑 공준

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

www.acmicpc.net

소수구하기 링크(백준 1929)

 


<<소스코드>> 맞은답

import math

#소수를 구하는 함수, 자세한 설명은 1929번 포스팅
def prime(n): 
    if n==1:
        return False
    else:
        for i in range(2,int(math.sqrt(n))+1):
            if n%i == 0:
                return False
        return True

# 2부터 246912 까지 담은 리스트 생성 ( +1 해줌/ 246912까지 확인하려고)
general_list = list(range(2,246912))
prime_list = [] #소수 빈리스트를 만들고 리스트에서 소수이면 prime_list에 추가해줬다.
for p in general_list:
    if prime(p):
        prime_list.append(p)

# n과 2n 사이의 소수를 구하는 과정
while True:
    a = int(input()) # input된 n값
    if a == 0: #a가 0이면 while문 종료
        break
    cnt = 0
    for i in prime_list: #소수리스트에서 a와 2a 사이에 있는 소수만 골라서 카운트해준다.
        if a < i <= 2*a:
            cnt += 1
    print(cnt)

<<틀린답>> 

import math

def prime(n):
    if n==1:
        return False
    else:
        for i in range(2,int(math.sqrt(n))+1):
            if n%i == 0:
                return False
        return True

prime_list = []
for p in range(2,246913):
    if prime(p):
        prime_list.append(p)

while True:
    a = int(input())
    if a == 0:
        break
    cnt = 0
    for i in range(a,(2*a)+1): #비효율코드, i는 a만 돌면 되지만, (2a-a) i가 26만번 돌아야 함
        if i in prime_list:
            cnt += 1
    print(cnt)

<<결과값>> 

1
0
10
4
13
3
100
21
1000
135
10000
1033
100000
8392
0

 


 

소수리스트를 구했음에도 시간초과가 났다. 이유가 뭘까 하고 곰곰히 맞은답과 비교했더니 이 부분에서 비효율적으로 for문을 돌리고 있었다... 

prime_list에 2부터 26만까지의 소수를 넣어놓고, i가 prime_list를 한번씩 돌면 약 26만번을 돌게 되는데, 

for문에서 range로 a만큼을 더 반복해야하니 a * 26만이 되어버린다. 

   for i in range(a,(2*a)+1):
        if i in prime_list:
            cnt += 1

맞은답을 보면, i는 prime_list 26만개를 돌면서 그냥 밑에 조건에 들어가는지만 체크하면 된다. 그래서 26만번만 그냥 돌면 된다.ㅜㅜㅜ

왜 이 생각을 못했지? 시간복잡도를 고려하면서 문제를  풀어야겠다.

    for i in prime_list:
        if a < i <= 2*a:
            cnt += 1
728x90
반응형