본문 바로가기

Programming/알고리즘

백준 공유기설치

반응형

https://www.acmicpc.net/problem/2110

 

 

백준 공유기설치 문제이다.
이진탐색 문제인데 꽤나 신박한 문제였다.
문제를 본 순간 드는 생각은 공유기를 하나하나씩 둬 보면서 경우의 수를 따져보는 것이었다. 다시 말해서 완전탐색으로 풀 수 있는 문제지만 역시 백준문제답게 시간제한이 있으므로 완전탐색보다 빠른 이진탐색을 이용하면 풀 수 있을거라 생각했다.

공유기설치하는 집 사이의 최소거리를 이진탐색으로 찾는것을 생각하는 것이 꽤나 어려웠다.

 

 

해결 알고리즘

1. 이진탐색으로 nCurDst를 설정한다.

2. 설정한 nCurDst로 공유기를 다 설치할 수 있는지 확인한다. (CheckDistance())

3. 공유기를 설치할 수 있으면 더 큰 nCurDst로 다시 탐색하고 해당 nCurDst를 저장한다.

   3-1. 공유기를 설치할 수 없으면 더 작은 nCurDst로 다시 탐색한다.

4. 종료조건은 더 이상 탐색할 nCurDst가 없을때 종료한다.

 

소스코드는 다음과 같다.

   #include <iostream>
#include <algorithm>
#include <assert.h>

using namespace std;

// brief : 현재 nCurDst로 공유기 설치가 가능한지 검사.
//input : 집의 위치정보배열, 탐색해볼 distance, 집 개수, 공유기 개수
bool CheckDistance(int home[], int dist, int N, int M)
{
	int visit = 0;
	M--;	// 첫 번째 집에 공유기 설치.

	for (int i = 1; i < N; i++)
	{
		if (M > 0)	// 아직 설치할 공유기가 남아있는 경우
		{
			if (home[i] - home[visit] >= dist)
			{
				visit = i;
				M--;
			}
		}
		else // M == 0, 해당 dist로 공유기 전체설치 성공. dist 더 큰경우를 탐색해보자.
		{
			return true;
		}
	}

	if (M > 0)	// dist 줄여야함.
	{
		return false;
	}
	else if (M == 0)	//해당 dist로 성공. dist 더 큰경우를 탐색해보자.
	{
		return true;
	}
	else 
	{
		// none
	}
}

int main()
{
	int N, M;
	int home[200000];
	cin >> N >> M;
	for (int i = 0; i < N; i++)
	{
		cin >> home[i];	// 집 입력받기(배열)	
	}

	//sorting 한번 해야돼
	sort(home, home + N);

	int dst_save = 1;	//답
	int nMaxDst = (home[N - 1] - home[0]) / (M - 1);
	int nMinDst = 1;
	int nCurDst = 1;

	while (nMinDst <= nMaxDst)
	{
		nCurDst = (nMaxDst + nMinDst) / 2;

		if (CheckDistance(home, nCurDst, N, M))	// 공유기 설치 성공한 경우. 더 큰경우 탐색
		{
			if (nCurDst == nMaxDst)
			{
				cout << nCurDst;
				break;
			}
			dst_save = nCurDst;
			nMinDst = nCurDst + 1;

			
		}
		else // 설치가 안되면 작은 케이스를 탐색해야하거나 or 종료조건인 경우다.
		{
			if (nMinDst == nMaxDst) // 종료조건
			{
				cout << dst_save;
				break;
			}
			else //left side search
			{
				nMaxDst = (nCurDst == nMinDst ? nCurDst : nCurDst - 1);
			}
		}
	}

	return 0;
}
반응형

'Programming > 알고리즘' 카테고리의 다른 글

[백준 N과 M(1)] 백트래킹 문제  (0) 2020.02.29
백준 토마토문제  (0) 2020.02.11
백준 구슬탈출2  (0) 2020.02.11
백준 나무자르기  (0) 2020.02.11
백준 유진수  (0) 2020.02.11