백준 블로그에서 본 글을 재구성한 글이고, 백준이 날라가서 임시로 작성한 글임. 누가 쓰셨는진 모르겠는데 알려주시면 출처 남김
레드가 아니면 이분 탐색이나 공부하라는 엄닉 센세의 말을 잘 새겨들을 것.
문제 단순화
수열 a1,a2,…,an이 있고 ax=ax+1를 만족하는 정수 x가 유일할 때 정수 x를 찾으시오.
방법론
lo=1, hi=n라는 변수를 선언한다.
lo+1=hi가 되기 전까지 다음을 반복한다:
mi=⌊2lo+hi⌋라고 정의하고, alo=ami라면 lo:=mi를, 아니면 hi:=mi를 수행한다.
정당성
alo=a1, ahi=an가 유지되므로 alo=ahi도 유지된다.
따라서 lo+1=hi가 되었다면 x=lo임을 알 수 있다.
코드
int lo = 1, hi = n;
while (lo + 1 < hi) {
int mi = (lo + hi) / 2;
(a[lo] == a[mi] ? lo : hi) = mi;
}
적용
이 방법을 여러 문제에 적용하기 위해서는, 우선 값을 두 가지 종류로 변환해야 한다.
예를 들어, 증가하는 수열 b1,b2,…,bn에 값 v가 존재하는지, 존재한다면 어느 위치에 존재하는지 찾고 싶을 수 있다.
수열 a0,a1,…,an+1에 대해 a0=false, ai=(bi≥v), an+1=true라 정의하고 위에서 설명한 이분 탐색을 수행하자.
처음으로 bx≥v가 되는 위치 x를 찾을 수 있는데, x<n+1인지, bx=v인지 정도만 체크하면 수열에 v가 존재하는지와 어느 위치에 존재하는지를 찾을 수 있다.
이와 같이 거의 모든 이분 탐색 문제는 값을 두 종류로 변환함으로써 이 방법론을 적용할 수 있다.
아직 댓글이 없습니다.