This repository was archived by the owner on Mar 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
[2023-09-15] sumin #208 #228
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
""" | ||
풀이 시간: 22분 | ||
|
||
<input> | ||
t: 테스트케이스 | ||
n: 찾아야 하는 골드바흐 파티션의 합이 되는 짝수(4 ≤ n ≤ 10,000) | ||
|
||
<solution> | ||
합이 n이 되는 짝수를 어떻게 찾을 수 있을까? | ||
- 2 ~ 최대 10,000개까지의 소수 중 합이 n이 되게 하는 두 소수를 찾기 위해서 투포인터를 사용할 수 있다. | ||
- 소수가 정렬돼있는 상태이기 때문에 left는 시작 인덱스, right은 끝 인덱스로 초기화 후, 두 소수의 합을 계속해서 target과 비교하며 포인터를 이동시킨다. | ||
|
||
<시간복잡도> | ||
O(nlog(logn)): 에라토스테네스의체 | ||
find_parition 함수는 최대 O(n) | ||
|
||
|
||
뭔가 더 최적화할 수 있는 방법이 있을 것 같은데 생각이 안남.... 여러분의 신박한 풀이 기다립니다.. | ||
""" | ||
|
||
import sys | ||
input = sys.stdin.readline | ||
from typing import List | ||
|
||
def find_prime_numbers(mx: int) -> List: | ||
""" | ||
mx: 2 ~ mx까지 중 소수인 수 | ||
""" | ||
arr = [True] * (mx+1) | ||
arr[0] = arr[1] = False # 0과 1은 소수가 아님 | ||
|
||
# 에라토스테네스의 체 | ||
for i in range(2, int(mx**(1/2))+1): | ||
if arr[i]: # i가 소수인 경우 | ||
j = 2 | ||
while i * j <= mx: | ||
arr[i*j] = False | ||
j += 1 | ||
|
||
return [i for i in range(len(arr)) if arr[i]] | ||
|
||
|
||
def find_partition(target: int, prime_number: List) -> List: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 투 포인터를 통해 접근하는 방법도 존재 할 수 있었군요! 저는 그냥 해시테이블을 통해서 있어야할 소수 값이 존재하는지를 확인하는 방식으로 접근하고 결과값의 최소 차이를 기억하는 방식을 사용했었는데 투 포인터를 사용하면 조금 더 시간 복잡도를 개선 할 수 있을 것 같습니다! 고생하셨습니다 수민님!! |
||
""" | ||
target: 찾아야 하는 골드바흐 파티션의 합이 되는 짝수 | ||
prime_number: n까지의 소수 배열 | ||
""" | ||
left, right = 0, len(prime_number)-1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right을 target으로 두어도 될 것 같습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. target은 실제 값이고 right은 끝인덱스를 의미하는거라 target으로 두면 안돼요 지수님! |
||
diff = target # 현재까지 찾은 최소 차이 | ||
result = [0, 0] # 최소 차이를 가지는 골드바흐 파티션 | ||
|
||
# 투포인터 | ||
while left <= right: | ||
cur_sum = prime_number[left] + prime_number[right] | ||
if cur_sum == target: # 두 소수의 합이 target이 될 때 | ||
if diff > prime_number[right] - prime_number[left]: # 최소 차이 업데이트 | ||
diff = prime_number[right] - prime_number[left] | ||
result[0], result[1] = prime_number[left], prime_number[right] | ||
left += 1 | ||
elif cur_sum < target: # 두 소수의 합이 target보다 작다면 left를 증가 | ||
left += 1 | ||
else: # 두 소수의 합이 target보다 크다면 right를 감소 | ||
right -= 1 | ||
return result | ||
|
||
# 테스트 케이스의 수 | ||
t = int(input()) | ||
primes = find_prime_numbers(10000) # 입력으로 들어올 수 있는 가장 큰 n은 10,000이기 때문에 미리 10,000까지 모든 소수를 구해둠 | ||
for _ in range(t): | ||
n = int(input()) | ||
print(*find_partition(n, primes)) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[i for i in range(len(arr)) if arr[I]] 해당 검사를 다시 len(arr) 만큼 해줘야하니 여기서 소수를 리스트에 하나씩 append 하는 형식으로 최적화를 할 수 있을 것 같습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 그럼 새로운 리스트를 하나 만들어서 i를 append 해주고 해당 리스트를 반환하는 식으로 해야겠네요..!
감사합니다 우열님~!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Woo-Yeol 에라토스테네스의 체는 소거법이기 때문에 일단 모든 수가 소수라고 가정 하고 순회하며 소수가 아닌 수들을 지워줘야 최종적으로 소수인 값들을 구할 수 있기 때문에 여기서 append는 해서 소수를 구하기는 어려울 것 같습니다.
다만 34번 라인의 주석을 i가 현재 소수로 표시되어있는 경우라고 바꿔주면 표현이 명확해질 수 있겠네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 제가 위에 코멘트 남긴게 pending으로 돼있었군요!
지수님 말씀하신 34번째 라인에서 i를 append해주는 것만으로도 위에 소수를 입력받는 list를 하나 만들어주면 가능해요!