def sequnetial_search(n, target, array):
for i in range(n):
if array[i] == target:
return i + 1 #현재 위치 반환, 인덱스 + 1
시작점
, 끝점
, 중간점
# 재귀
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)
# 반복문
def binary_search(array, target, start, end):
while start<= end:
mid = (start+end)//2
if array[mid] == target:
return mid
elif array[mid] > target :
end = mid -1
else :
start = mid +1
return None
c++로 구현한 이진탐색은 다음과 같다.
int binary_serach(int data[], int size, int d){
int s =0;
int e = size -1;
int m = 0;
while (s <= e){
m = (s+e)/2;
if(data[m]==d) return m;
else if (data[m] >d) e= m-1;
else s = m+1;
}
return -1;
}
동빈이네 전자 매장에는 부품이 N개 있다. (부품마다 고유번호 존재한다.)
어느날 손님이 M개 종류의 부품을 대량 구매하겠다고 한다.
문의한 부품 M개종류를 모두 확인해서 가게안에 부품이 존재하는지 확인해보자.
// 부품찾기
// binary_Serach
#include <bits/stdc++.h>
using namespace std;
bool bs(vector<int>& data, int target){
int start = 0;
int end = data.size()-1;
int mid = 0;
while(start<=end){
mid = (start+end)/2;
if(data[mid]==target){
return true;
}
else if(target>data[mid]){
start = mid+1;
}
else{
end = mid-1;
}
}
return false;
}
int N, M;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> N;
vector<int> store(N, 0);
for (int i = 0; i < N; i++)
{
cin >> store[i];
}
cin>>M;
vector<int> request(M,0);
for (int i = 0; i < M; i++)
{
cin >> request[i];
}
for(int i=0; i<M; i++){
if(bs(store, request[i])){
cout<<"yes ";
}
else cout<<"no ";
}
}
이 문제는 계수정렬, 또는 set로도 풀 수 있다. (N의 범위가 백만 이하이기에)
손님이 왔을때 요청한 총 길이가 M일 때 적어도 M만큼의 떡을 얻기 위해 절단기에 설정할 수 있는 높이의 최댓값을 구하는 프로그램을 작성하시오.
#include <bits/stdc++.h>
using namespace std;
int N, M;
int max_el;
vector<int> rcs;
int get_left_rcs(int standard)
{
if(standard >= max_el) return 0; //max_el부터 탐색했으면 이런 문제가 없었을 텐데..
int result = 0;
for (int i = 0; i < N; i++)
{
if (standard < rcs[i])
result += rcs[i] - standard;
}
return result;
}
int guillotine()
{
int answer = 0;
int start = 0;
int end = 2000000000;
int mid = 0;
while (start <= end)
{
mid = (start + end) / 2;
int result = get_left_rcs(mid);
if (result >= M)
{
answer = max(answer, mid);
start = mid + 1;
}
else
{
end = mid - 1;
}
}
return answer;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> N >> M;
rcs.resize(N, 0);
for (int i = 0; i < N; i++)
{
cin >> rcs[i];
}
sort(rcs.begin(), rcs.end());
max_el = rcs[N-1];
cout << guillotine();
}
전형적인 이진 탐색 문제이자 파라메트릭 서치(Parametric Search)
문제이다.
최적화문제를 결정 문제로 바꾸어 해결하는 기법이다.
원하는 조건을 만족하는 가장 알맞는 값을 찾는 문제에서 자주 이용된다.
이번 문제의 경우 절단기 높이(탐색 범위)는 1~10억 정수중 하나인데, 절단기 높이가 10억이므로, 이진 탐색을 이용하면 31*\N 즉, 최대 3,000만 번 정도의 연산으로 문제를 풀 수 있다.
파라메트릭 서치의 경우 재귀적으로 구하면 귀찮아 지기 때문에, 반복문을 이용하면 더 간단하게 풀 수 있다.