Skip to content
This repository was archived by the owner on Mar 18, 2024. It is now read-only.

Commit 801f889

Browse files
committed
Create 골드바흐의 추측 sumin.py
1 parent cd4d2c0 commit 801f889

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

BOJ/골드바흐의 추측/sumin.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
풀이 시간: 22분
3+
4+
<input>
5+
t: 테스트케이스
6+
n: 찾아야 하는 골드바흐 파티션의 합이 되는 짝수(4 ≤ n ≤ 10,000)
7+
8+
<solution>
9+
합이 n이 되는 짝수를 어떻게 찾을 수 있을까?
10+
- 2 ~ 최대 10,000개까지의 소수 중 합이 n이 되게 하는 두 소수를 찾기 위해서 투포인터를 사용할 수 있다.
11+
- 소수가 정렬돼있는 상태이기 때문에 left는 시작 인덱스, right은 끝 인덱스로 초기화 후, 두 소수의 합을 계속해서 target과 비교하며 포인터를 이동시킨다.
12+
13+
<시간복잡도>
14+
O(nlog(logn)): 에라토스테네스의체
15+
find_parition 함수는 최대 O(n)
16+
17+
18+
뭔가 더 최적화할 수 있는 방법이 있을 것 같은데 생각이 안남.... 여러분의 신박한 풀이 기다립니다..
19+
"""
20+
21+
import sys
22+
input = sys.stdin.readline
23+
from typing import List
24+
25+
def find_prime_numbers(mx: int) -> List:
26+
"""
27+
mx: 2 ~ mx까지 중 소수인 수
28+
"""
29+
arr = [True] * (mx+1)
30+
arr[0] = arr[1] = False # 0과 1은 소수가 아님
31+
32+
# 에라토스테네스의 체
33+
for i in range(2, int(mx**(1/2))+1):
34+
if arr[i]: # i가 소수인 경우
35+
j = 2
36+
while i * j <= mx:
37+
arr[i*j] = False
38+
j += 1
39+
40+
return [i for i in range(len(arr)) if arr[i]]
41+
42+
43+
def find_partition(target: int, prime_number: List) -> List:
44+
"""
45+
target: 찾아야 하는 골드바흐 파티션의 합이 되는 짝수
46+
prime_number: n까지의 소수 배열
47+
"""
48+
left, right = 0, len(prime_number)-1
49+
diff = target # 현재까지 찾은 최소 차이
50+
result = [0, 0] # 최소 차이를 가지는 골드바흐 파티션
51+
52+
# 투포인터
53+
while left <= right:
54+
cur_sum = prime_number[left] + prime_number[right]
55+
if cur_sum == target: # 두 소수의 합이 target이 될 때
56+
if diff > prime_number[right] - prime_number[left]: # 최소 차이 업데이트
57+
diff = prime_number[right] - prime_number[left]
58+
result[0], result[1] = prime_number[left], prime_number[right]
59+
left += 1
60+
elif cur_sum < target: # 두 소수의 합이 target보다 작다면 left를 증가
61+
left += 1
62+
else: # 두 소수의 합이 target보다 크다면 right를 감소
63+
right -= 1
64+
return result
65+
66+
# 테스트 케이스의 수
67+
t = int(input())
68+
primes = find_prime_numbers(10000) # 입력으로 들어올 수 있는 가장 큰 n은 10,000이기 때문에 미리 10,000까지 모든 소수를 구해둠
69+
for _ in range(t):
70+
n = int(input())
71+
print(*find_partition(n, primes))

0 commit comments

Comments
 (0)