https://school.programmers.co.kr/learn/courses/30/lessons/64062
해당 문제는 이진 탐색 중 파라메트릭 서치 문제로, 건널 수 있는 인원의 최소와 최대 범위를 이진 탐색을 통해 탐색하여 건널 수 있는 인원 중 최대 인원을 구해주었다.
1) start
를 1, end
를 200,000,000 으로 초기화 한다.
stones
내의 각 원소들의 값은 1 이상 200,000,000 이하인 자연수로 지정됨.2) stones
벡터를 복사하여 저장할 stones_copy
벡터를 선언해준다.
3) end
가 start
보다 크거나 같지 않을 때까지 이진 탐색을 반복 해준다.
mid
를 start
와 end
의 중간값으로 초기화 해준다.stones_copy
에 stones
를 그대로 복사한다.count
를 선언한다.stones_copy
를 처음부터 끝까지 돌면서 연속된 0의 개수를 확인한다. count
를 1 증가시킨다.count
를 0으로 초기화한다. (연속성이 깨지게 되므로)count
가 k개 이상이 되는 순간 루프를 빠져나간다. (건널 수 없는 경우에 도달)count
의 개수를 기준으로 start
와 end
의 위치를 옮겨준다.mid
이상은 불가능하므로 mid
미만 범위 탐색 -> end = mid - 1answer
를 mid
로 초기화하고, mid
를 초과하는 값도 탐색4) 이진 탐색이 종료된 이후 answer
에 최대 인원이 저장되는데, 이 때 answer
에 +1을 해주어야 한다.
mid가
건너는 인원이라고 가정했을 때 건널 수 있는 경우인지 판별하는데, 판별 기준이 mid
명이 건너고 난 뒤의 상태에 대해 판별된다.#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> stones;
int solution(vector<int> stones, int k)
{
int start = 1, end = 200000000, answer;
vector<int> stones_copy;
while (end >= start)
{
int mid = start + (end - start) / 2;
stones_copy = stones;
// 연속으로 0이 나올 때 count를 1씩 증가시키고, 연속성이 깨지면 다시 count를 0으로 초기화
int count = 0;
for (int i = 0; i < stones_copy.size(); i++)
{
if (stones_copy[i] - mid <= 0)
count++;
else
count = 0;
// 연속으로 나온 0의 개수가 가능한 거리를 넘으면 바로 반복 종료
if (count >= k)
break;
}
if (count >= k) // 건너는 인원을 너무 많이 잡아 건널 수 있는 거리 초과 -> mid 이상은 불가능하므로 mid 미만 값 탐색
end = mid - 1;
else // 건너는 인원을 너무 적게 잡거나 딱 맞게 잡아 거리 안에 가능 -> 일단 answer를 mid로 초기화하고 mid 초과 값도 탐색
{
answer = mid;
start = mid + 1;
}
}
return answer + 1; // mid가 n이면 n번째 인원을 통과하고도 한 명 더 통과할 수 있는 상태이므로 +1
}