

์ด๋ถ ํ์(binary search)๋, ์ด๋ค ๋ฐฐ์ด๊ณผ ์ฐพ๊ณ ์ ํ๋ ์๊ฐ ์์ ๋, ์ฐพ๊ณ ์ ํ๋ ๋ฒ์๋ฅผ ์ ๋ฐ์ฉ ์ขํ๊ฐ๋ฉฐ ๋น ๋ฅด๊ฒ ํด๋น ๊ฐ์ ์์น๋ฅผ ์ฐพ์๋ด๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ์์ ์์ฃผ ๋ฑ์ฅํ๋ ๋ํ์ ์ธ ํ์ ๊ธฐ๋ฒ์ผ๋ก, ๋จ์ํ ์ ๋ ฌ ๋ฐฐ์ด ํ์๋ถํฐ, ๊ฒฝ๊ณ๊ฐ ์ฐพ๊ธฐ, ์์ฉ ๋ฌธ์ ๊น์ง ๋งค์ฐ ๋ค์ํ ํํ๋ก ์ถ์ ๋ฉ๋๋ค. ๋งค ๋ฐ๋ณต๋ง๋ค ๊ฒ์ ๋ฒ์๋ฅผ ์ ๋ฐ์ผ๋ก ์ค์ด๊ธฐ์ O(log n)์ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋๋ค. ๋ค๋ง, ๊ฐ์ ๋์๋ฅผ ๋น๊ตํ๋ฉฐ ๋ฒ์๋ฅผ ์ก๊ธฐ์ ๋ฐฐ์ด์ด ๋ฐ๋์ ์ ๋ ฌ๋จ์ ์ ์ ๋ก ํฉ๋๋ค.
๊ตฌํ: ๋ฐ๋ณต vs. ์ฌ๊ท
์ด๋ถ ํ์์ ๋จผ์ ์์ ์ธ๋ฑ์ค์ ๋ ์ธ๋ฑ์ค๋ฅผ ์ก๊ณ , ๊ทธ ๋์ ์ค๊ฐ (๋๋ ์ ๋๋ ๋จ์ด์ง ๊ฒฝ์ฐ ํ ์นธ ์ผ์ชฝ) ์ธ๋ฑ์ค๋ฅผ ์ก๋ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ํํ ๊ฐ์ ์ธ๋ฑ์ค๋ฅผ ์ฐพ์ ๋๊น์ง ์์, ์ค๊ฐ, ๋ ์ธ๋ฑ์ค๋ฅผ ์๋์ ๊ฐ์ด ๊ณ์ ์กฐ์ ํ๋ ๊ฒ์ผ๋ก ์ด๋ฃจ์ด์ง๋๋ค.
๋ฐ๋ณต์ผ๋ก ๊ตฌํํ๊ธฐ
๋ฐฑ๋ฌธ์ด ๋ถ์ฌ์ผ๊ฒฌ, ๋ฐ๋ณต์ผ๋ก ๊ตฌํ๋ Python ์ฝ๋๋ฅผ ๋ณด์๊ฒ ์ต๋๋ค.
def binary_search_itr(arr, target): # arr: ์ ์ฒด ๋ฐฐ์ด, target: ์ฐพ๊ณ ์ ํ๋ ๊ฐ
left = 0
right = len(arr) - 1 # ๊ฒ์ ๋ฒ์๋ [left, right]
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid # ๊ฐ์ ์ฐพ์์ผ๋ฉด ํด๋น ์ธ๋ฑ์ค ๋ฐํ
elif arr[mid] < target:
left = mid + 1 # ์ค๋ฅธ์ชฝ ๊ตฌ๊ฐ์ผ๋ก ์ด๋
else:
right = mid - 1 # ์ผ์ชฝ ๊ตฌ๊ฐ์ผ๋ก ์ด๋
return -1 # ๊ฐ์ ์ฐพ์ง ๋ชปํ์ ๊ฒฝ์ฐ
๊ฐ๋ น, [1, 3, 4, 5, 7, 9, 11, 22, 33, 44, 55, 66]๋ผ๋ ๋ฐฐ์ด์ด ์๊ณ , ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ 22์ด๋ผ๊ณ ๊ฐ์ ํ์ฌ, ์๋์ ๊ฐ์ด ๋ฐ๋ณต๋ฌธ์ ๋ฐ๋ผ๊ฐ๋ด ์๋ค.
๋ฐ๋ณต๋ฌธ ๋ฐ๋ผ๊ฐ๊ธฐ

๋ฐ๋ณต๋ฌธ์ ์ฒ์ ๋ค์ด์ค๋ฉด left=0, right=11์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ mid๋ (0+11)//2, ์ฆ 5๊ฐ ๋ฉ๋๋ค. ์ด๋ ๊ณง 0๋ถํฐ 11๊น์ง์ ์ธ๋ฑ์ค๋ฅผ ๋ฒ์๋ก ์ก๊ณ , ๊ทธ ๊ฐ์ด๋ฐ์ ์ซ์๋ฅผ target(=22)๊ณผ ๋น๊ตํ๋ ๊ฒ์ ๋๋ค. arr[5]=9์ด๋ฏ๋ก, 22๋ณด๋ค ์์ต๋๋ค. ์ฆ ์์์ ์ธ left ๊ฐ์ mid+1, ์ฆ 6์ผ๋ก ์กฐ์ ํฉ๋๋ค. ๋ฐ๋ณต๋ฌธ ๋ง์ง๋ง์ left, mid, right๋ ๊ฐ๊ฐ 6, 5, 11๋ก ์กฐ์ ๋ฉ๋๋ค.

๋ ๋ฒ์งธ ๋ฐ๋ณต์์ left=6, right=11๋ก ์์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ mid๋ (6+11)//2, ์ฆ 8์ ๋๋ค. ๋ค์ ๋งํด, 6๋ถํฐ 11๊น์ง์ ์ธ๋ฑ์ค๋ฅผ ๋ฒ์๋ก ์ก๊ณ , ๊ทธ ๊ฐ์ด๋ฐ์ ์ซ์๋ฅผ target(=22)๊ณผ ๋น๊ตํ๋ ๊ฒ์ ๋๋ค. arr[8]=33์ด๋ฏ๋ก, 22๋ณด๋ค ํฝ๋๋ค. ์ด๋ฒ์๋ ๋์ ์ธ right๊ฐ์ mid-1, ์ฆ 7๋ก ์กฐ์ ํฉ๋๋ค. ๋ฐ๋ณต๋ฌธ ๋ง์ง๋ง์ left, mid, right๋ ๊ฐ๊ฐ 6, 8, 7๋ก ์กฐ์ ๋ฉ๋๋ค.

์ธ ๋ฒ์งธ ๋ฐ๋ณต์์ left=6, right=7๋ก ์์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ mid๋ (6+7)//2, ์ฆ 6์ ๋๋ค. ๋ค์ ๋งํด, 6๋ถํฐ 7๊น์ง์ ์ธ๋ฑ์ค๋ฅผ ๋ฒ์๋ก ์ก๊ณ , ๊ทธ ๊ฐ์ด๋ฐ์ ์ซ์๋ฅผ target(=22)๊ณผ ๋น๊ตํ๋ ๊ฒ์ ๋๋ค. arr[6]=11์ด๋ฏ๋ก, 22๋ณด๋ค ์์ต๋๋ค. ์ด๋ฒ์๋ ์์์ ์ธ left ๊ฐ์ mid+1, ์ฆ 7๋ก ์กฐ์ ํฉ๋๋ค. ๋ฐ๋ณต๋ฌธ ๋ง์ง๋ง์ left, mid, right๋ ๊ฐ๊ฐ 7, 6, 7๋ก ์กฐ์ ๋ฉ๋๋ค.

๋ค ๋ฒ์งธ ๋ฐ๋ณต์์๋ ์์ ๋์ผํ ๊ณผ์ ์ผ๋ก, left=7, mid=7, right=7๋ก ์์ํฉ๋๋ค. ์ ๋ค ๊ฐ์ ๊ฐ์ด๋ `if arr[mid] == target` ์กฐ๊ฑด์ ๊ฑธ๋ฆฝ๋๋ค. ๊ฐ์ ์ฐพ์์ต๋๋ค. arr[7]=22. ์ด์ mid์ 7์ ๋ฆฌํดํจ์ผ๋ก์จ ํจ์๊ฐ ์ข ๋ฃ๋ฉ๋๋ค.
์ฌ๊ท๋ก ๊ตฌํํ๊ธฐ
์๋๋ ๋์ผํ ๊ธฐ๋ฅ์ ์ฌ๊ท๋ก ๊ตฌํํ ์ฝ๋์ ๋๋ค.
def binary_search_rcv(arr, target, left=0, right=None):
if right is None:
right = len(arr) - 1 # ์ต์ด ํธ์ถ ==> right ์ด๊ธฐํ
if left > right:
return -1 # base case && ๊ฐ์ด ์์
mid = (left + right) // 2
if arr[mid] == target:
return mid # base case && ๊ฐ์ด ์์ => ํด๋น ์ธ๋ฑ์ค ๋ฆฌํด
elif arr[mid] < target:
return binary_search_rcv(arr, target, mid + 1, right) # ์ค๋ฅธ์ชฝ ๊ตฌ๊ฐ์์ ์ฌ๊ท
else:
return binary_search_rcv(arr, target, left, mid - 1) # ์ผ์ชฝ ๊ตฌ๊ฐ์์ ์ฌ๊ท
์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ์ ์๋ ๋ฌธ์ ๊ฐ ๋ฐ๋ก ๋ฐฑ์ค 10815 "์ซ์ ์นด๋"์ ๋๋ค. https://www.acmicpc.net/problem/10815
์ฐธ๊ณ ๋ก ์๋๋ naive approach๋ก ๊ตฌํํ ์ฝ๋์ธ๋ฐ, ํน-์ if in ๋ฌธ๋ฒ์ด ๋๋ฆ์ ์ต์ ํ๋ฅผ ๊ฑฐ์ณ์ ๋ต์ ๋น ๋ฅด๊ฒ ์ฐพ์๋ด์ง ์์๊น ํ์ผ๋, ์๊ฐ ์ด๊ณผ๊ฐ ๋ฉ๋๋ค.
import sys
input = sys.stdin.readline
cards_count = int(input())
cards_in_pkt = sorted(map(int,input().split()))
tests_count = int(input())
tests = list(map(int,input().split()))
result = [1 if a in cards_in_pkt else 0 for a in tests]
print(*result)
์์ฉ: ์ ํํ ๊ฐ์ด ์์ ๊ฒฝ์ฐ, '์ต์์ ์ต๋' ๋ฌธ์
๊ฐํน ์ ํํ ํ๊น์ด ์ฃผ์ด์ง์ง ์๋ ๋ฌธ์ ๋ค์ด ์์ต๋๋ค. ๋ฐ๋ก ๋ฐฑ์ค 2805 "๋๋ฌด ์๋ฅด๊ธฐ"์ ๊ฐ์ ๋ฌธ์ ๋ค์ ๋๋ค.

๋ง์ง๋ง ๋ฌธ๋จ์ ๋์จ ๋ฐ์ ๊ฐ์ด, "์ ์ด๋ M๋ฏธํฐ๋ฅผ ๋ณด์ฅํ๋ ์ ๋จ๊ธฐ์ ๋์ด์ ์ต๋๊ฐ"์ ๊ตฌํ๋ ๋ฌธ์ ์ ๋๋ค. ์ ํํ ํ๊น์ ์ฐพ๋ ๊ฒ ์๋๋ผ ๊ฐ๋ฅํ ๊ฐ ์ค ์ต๋๋ฅผ ๊ตฌํ๋ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ์ด๋ถ ํ์์ ์๋์ ๊ฐ์ด ์์ฉ๋ ์ ์์ต๋๋ค.
count, target_num = map(int,input().split())
trees = list(map(int,input().split()) )
low, high = 0, max(trees)
while low <= high:
mid = (low + high) // 2
sum_cut = sum((trees[i] - mid) for i in range(len(trees)) if trees[i] > mid)
if sum_cut >= target_num:
low = mid + 1 # ๋ ๋ง๋ค ==> low๋ฅผ ๊ฐฑ์
else:
high = mid - 1 # ๋ชจ์๋ผ๋ค ==> high๋ฅผ ๊ฐฑ์
print(result)
์ด๋ ์ ํ์ ์ธ parametric search (ํ๋ผ๋ฉํธ๋ฆญ ์์น) ๋ฌธ์ ๋ก, ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ต๋๊ฐ์ ์ฐพ๋ 'upper bound' ํจํด์ด๊ธฐ์ ์๋ ์ค๋ช ๋๋ฆด `bisect_right`์ ๋์ผํ ๊ธฐ๋ฅ์ ์ํํฉ๋๋ค.
bisect_left vs. bisect_right
Python ๋ด์ฅ ๋ชจ๋ ์ค `bisect`๋ ์ ๋ ฌ๋ ๋ฆฌ์คํธ์ ๊ฐ์ ์ฝ์ ํ๊ฑฐ๋ ์์น๋ฅผ ์ฐพ๋ ํจ์๋ค์ ์ ๊ณตํฉ๋๋ค. ๋ํ์ ์ผ๋ก๋ `bisect`, `bisect_left`, `bisect_right`๊ฐ ์๊ฒ ์ต๋๋ค.
ํต์ฌ ํจ์ ๋น๊ต
ํจ์ | ๋ฐํ ์์น | ์๋ฏธ |
bisect_left(a, x) | ์ผ์ชฝ ์ฝ์ ์์น | x๋ฅผ ๋ฃ์ ์ ์๋ ๊ฐ์ฅ ์ผ์ชฝ ์์น |
bisect_right(a, x) ๋๋ bisect(a, x) | ์ค๋ฅธ์ชฝ ์ฝ์ ์์น | x๋ฅผ ๋ฃ์ ์ ์๋ ๊ฐ์ฅ ์ค๋ฅธ์ชฝ ์์น |
์ฐธ๊ณ : `bisect()`๋ `bisect_right()`์ alias, ์ฆ, ๊ฐ์ ํจ์์ ๋๋ค.
์๋์ ๊ฐ์ด ์์ฑํ ์ฝ๋๋ฅผ ํตํด ๋น๊ตํด๋ด ์๋ค.
def bs_by_bisect(arr,target_num):
return (bisect_left(arr,target_num), bisect(arr,target_num), bisect_right(arr,target_num))
arr = [10, 20, 50, 66, 123, 214, 333, 444, 555, 777]
print("----------------------")
target_num = 49
print("target_num:",target_num, bs_by_bisect(arr,target_num))
target_num = 50
print("target_num:",target_num, bs_by_bisect(arr,target_num))
target_num = 51
print("target_num:",target_num, bs_by_bisect(arr,target_num))
print("----------------------")

๊ฒฐ๊ณผ๋ ์์ ๊ฐ์ต๋๋ค.
`bisect_left`๋ 49์ 50์์ ์ธ๋ฑ์ค 2, ์ฆ 20์ ์์น๋ฅผ ๋ฆฌํดํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ 51์ด ๋์ด์์ผ 50์ ์์น๋ฅผ ๋ฆฌํดํฉ๋๋ค. ๋ฐ๋ฉด `bisect_right`๋ 49์์๋ง 20์ ์์น๋ฅผ ๋ฆฌํดํ๋ฉฐ, 50๋ถํฐ๋ ๋ฐ๋ก 50์ ์์น๋ฅผ ๋ฆฌํดํฉ๋๋ค.
๋ ๋์๊ฐ๊ธฐ
์ง๊ธ๊น์ง ์ด๋ถ ํ์์ ๊ฐ๋ ์ผ๋ก๋ถํฐ ์์ํ์ฌ `bisect_left`, `bisect_right` ๋ฑ ์ด๋ค์ ๊ฐ๋ ์ ์์ฉํ ์ ํ๊น์ง ์์๋ณด์์ต๋๋ค. ์๋๋ ๋ฐฑ์ค 11053 "๊ฐ์ฅ ๊ธด ์ฆ๊ฐํ๋ ๋ถ๋ถ ์์ด"์ ๋๋ค. ์ด๋ถ ํ์์ ์์ฉํ์ฌ ์ง์ ๊ตฌํํด๋ณด์๊ธฐ๋ฅผ ์ถ์ฒ ๋๋ฆฝ๋๋ค.
'IT > ์ปดํจํ ์ ์ฌ๊ณ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
C์ธ์ด์ ๋ค์ค ํฌ์ธํฐ (0) | 2025.04.13 |
---|---|
Python ์ปดํ๋ฆฌํจ์ ๋ฐ ํํ์ ์ ๋ฆฌ (0) | 2025.03.27 |
[์คํฌ๋ฉ] CS:APP ๋นํธ์ฐ์ฐ ๊ณผ์ bits.c ๋ต์ (0) | 2016.11.06 |
์๋ ํ์ธ์.
ํฌ์คํ ์ด ์ข์๋ค๋ฉด "์ข์์โค๏ธ" ๋๋ "๊ตฌ๋ ๐๐ป" ํด์ฃผ์ธ์!