본문 바로가기

CS Study/algorithm

이진 탐색 문제풀이

1. 수 찾기 (백준 1920 번)

 

1920번: 수 찾기

첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들

www.acmicpc.net

 

직접 작성한 코드) 

 

n=int(input())
array=list(map(int, input().split()))
m=int(input())
targetlist=list(map(int,input().split()))


array.sort()
def binary_search(array, target,start,end):
    if start > end:
        return None

    mid =(start+end)//2
    if array[mid]==target:
        return mid
    elif array[mid] >  target:
        return binary_search(array,target,start,mid -1)
    else:
        return binary_search(array, target, mid+1, end)

for i in targetlist:
    result=binary_search(array,i,0,n-1)
    if result==None:
        print(0)
    else:
        print(1)

 

2. 숫자 카드 (백준 10815 번)

 

10815번: 숫자 카드

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,

www.acmicpc.net

 

직접 작성한 코드) 

n=int(input())
array=list(map(int, input().split()))
m=int(input())
targetlist=list(map(int,input().split()))
lastresult=[]

array.sort()
def binary_search(array, target,start,end):
    if start > end:
        return None

    mid =(start+end)//2
    if array[mid]==target:
        return mid
    elif array[mid] >  target:
        return binary_search(array,target,start,mid -1)
    else:
        return binary_search(array, target, mid+1, end)

for i in targetlist:
    result=binary_search(array,i,0,n-1)
    if result==None:
        lastresult.append(0)
    else:
        lastresult.append(1)

for i in lastresult:
    print(i,end=' ')

 

3. 가장 긴 증가하는 부분 수열 2 (백준 12015 번)

 

12015번: 가장 긴 증가하는 부분 수열 2

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)

www.acmicpc.net

 

참고 코드)

 

n=int(input())
array=list(map(int,input().split()))
import sys
from bisect import bisect_left

lis = []
result = 0
for num in array:
    if not lis:
        lis.append(num)
        result += 1
        continue
    
    if lis[-1] < num:
        lis.append(num)
        result += 1
    else:
        index = bisect_left(lis, num)
        lis[index] = num
    
  
print(result)

 

➡️ 핵심 아이디어

만약, 현재 lis이 10, 30, 40, 70으로 구성되어 있고, 현재 50이 들어갈 자리가 70이 있는 자리인 상황이라면 70을 50으로 교체해야 더 긴 수열을 연장할 수 있다.

왜냐하면, 10, 30, 40, 70 일때 60가 들어온다면 추가할 수 없지만 10, 30, 40, 50 일 경우에는 추가하여 result를 더 크게 만들 수 있다.

이를 위한 코드가 else: 이후의 코드이다.

 

4. 예산 (백준 2512번)

 

2512번: 예산

첫째 줄에는 지방의 수를 의미하는 정수 N이 주어진다. N은 3 이상 10,000 이하이다. 다음 줄에는 각 지방의 예산요청을 표현하는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 값들은 모두 1 이상

www.acmicpc.net

 

참고 코드) 

 

n=int(input())
array=list(map(int,input().split()))
number=int(input())

start,end=0,max(array)
total_budget=0

if sum(array)>=end:
    print(max(array))
    
else:
    while start<=end:
        mid=(start+end)//2
        total_budget=0
        for i in array:
            total_budget+=min(mid,i)
        if total_budget>number:
            end=mid-1
        else:
            start=mid+1
            
    print(mid)

 

➡️ 핵심 아이디어: 적절한 값을 찾아야하는 문제이다. 이진 탐색을 통하여 가장 큰 값을 바꾸며 합을 구하면서 적절 값을 찾는다.

 

'CS Study > algorithm' 카테고리의 다른 글

구현 문제풀이  (0) 2022.08.07
다이나믹 프로그래밍 문제 풀이  (0) 2022.07.31
기타 문제풀이  (0) 2022.07.22
DFS & BFS 문제 풀이  (0) 2022.07.19
정렬 알고리즘 (문제 풀이)  (0) 2022.07.14