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

[2023-09-15] wooyeol #208 #229

Merged
merged 1 commit into from
Sep 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions BOJ/골드바흐의 추측/wooyeol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""
골드바흐의 추측

풀이시간
20:44 ~ 21:28 (44분)

문제 조건
4 <= N <= 10,000
2 <= target <= 10,000인 짝수

시간 복잡도 :
O(값 입력 + 에라토스테네스의 체 만들기 + 골드바흐의 파티션 찾기)

접근법
무슨 알고리즘으로 풀이 할 수 있을까? -> 구현

1. 입력 받은 케이스 중 최대 값까지의 소수를 구하기 - 에라토스테네스의 체
2. 골드바흐 파티션 찾기 -> 두 소수의 차이가 가장 작은 것을 출력
- 가장 작은 소수 값부터 확인하며
- 작은 소수 값이 먼저 나오며 target 값에서 작은 소수 값을 제외한 값이 소수일 경우 중
- 두 소수의 차이가 최소일 경우 정답에 두 소수의 값 업데이트

"""
import sys
from collections import defaultdict

input = sys.stdin.readline

# Inputs
N = int(input())

## 정답
answer = [0] * N

## 입력받은 최대 정수
max_value = 0

## 입력받는 테스트 케이스 값
targets = []

# 테스트 케이스 입력 받기
for _ in range(N):
target = int(input())
targets.append(target)

# 최대 값 확인 및 업데이트
if target > max_value:
max_value = target

# 1. 최대 값까지 에라토스테네스의 체 만들기
table = [False, False] + [True] * (max_value-1)

## defaultdict를 사용한 이유 입력한 순서를 기억하고 in 연산의 시간 복잡도를 O(1)로 만들기 위해서
prime_numbers = defaultdict(bool)

## 2 이상 max_value 이하의 값까지 소수 확인 -> 10,000개까지 총 1229개의 소수
for num in range(2, max_value+1):
if table[num]:
prime_numbers[num] = True
for n in range(num, max_value+1, num):
table[n] = False
# print(prime_numbers.keys(), len(prime_numbers), max(prime_numbers))

# 2. 골드바흐의 파티션 찾기 -> 답이 무조건 있음 예외처리 필요 없음
for idx, target in enumerate(targets):
min_gap = 100001
# 소수 중에서
for p_num in prime_numbers.keys():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정렬되어있다면, 소수 크기(p_num)가 target을 넘어가면 break하는 로직을 추가해도 좋을 것 같습니다.

# 작은 소수 값이 먼저 나오며 target 값에서 작은 소수 값을 제외한 값이 소수일 경우 -> 골드바흐의 파티션
if (p_num <= target - p_num) and (target - p_num) in prime_numbers:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 전체적으로 주석이 깔끔하고 이 부분을 딕셔너리로 처리할 생각을 정말 좋은 아이디어라고 생각해요!!
시간도 O(1) 밖에 들지 않고..! 좋은 풀이 감사합니다 우열님!👍👍

# 만약 두 소수의 차이가 최소일 경우 정답 업데이트
if target - (2 * p_num) < min_gap:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아..!
(target - p_num) - p_num = target - (2 * p_num)이라
두 소수의 차이를 이렇게 표현하신 거군요!!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 제가 노트에 쓴 걸 옮겨적다보니 축약해서 적고 설명도 안 적었네요 ㅎㅎ 말씀해주신 내용이 맞습니다!

min_gap = target - (2 * p_num)
answer[idx] = (p_num, target - p_num)

for row in answer:
print(*row)