문제
인하대학교 후문 뒤쪽에는 어두운 굴다리가 있다. 겁쟁이 상빈이는 길이 조금이라도 어둡다면 가지 않는다. 따라서 굴다리로 가면 최단거리로 집까지 갈수 있지만, 굴다리는 어둡기 때문에 빙빙 돌아서 집으로 간다. 안타깝게 여긴 인식이는 굴다리 모든 길 0 ~ N을 밝히게 가로등을 설치해 달라고 인천광역시에 민원을 넣었다. 인천광역시에서 가로등을 설치할 개수 M과 각 가로등의 위치 x들의 결정을 끝냈다. 그리고 각 가로등은 높이만큼 주위를 비출 수 있다. 하지만 갑자기 예산이 부족해진 인천광역시는 가로등의 높이가 높을수록 가격이 비싸지기 때문에 최소한의 높이로 굴다리 모든 길 0~N을 밝히고자 한다. 최소한의 예산이 들 높이를 구하자. 단 가로등은 모두 높이가 같아야 하고, 정수이다.
다음 그림을 보자.
가로등의 높이가 H라면 왼쪽으로 H, 오른쪽으로 H만큼 주위를 비춘다.
다음 그림은 예제1에 대한 설명이다.
가로등의 높이가 1일 경우 0~1사이의 길이 어둡기 때문에 상빈이는 지나가지 못한다.
아래 그림처럼 높이가 2일 경우 0~5의 모든 길이 밝기 때문에 상빈이는 지나갈 수 있다.
입력
첫 번째 줄에 굴다리의 길이 N 이 주어진다. (1 ≤ N ≤ 100,000)
두 번째 줄에 가로등의 개수 M 이 주어진다. (1 ≤ M ≤ N)
다음 줄에 M 개의 설치할 수 있는 가로등의 위치 x 가 주어진다. (0 ≤ x ≤ N)
가로등의 위치 x는 오름차순으로 입력받으며 가로등의 위치는 중복되지 않으며, 정수이다.
출력
굴다리의 길이 N을 모두 비추기 위한 가로등의 최소 높이를 출력한다.
문제 링크
https://www.acmicpc.net/problem/17266
풀이
풀이는 정말 간단하다.
간격들 중 가장 큰 값을 찾아주면 된다.
전체를 다 채운다는 생각보다, 간격을 다 채운다고 생각하면 된다.
가로등이 모두 같은 것으로 통일되기 때문에 가장 넓은 간격을 채울 수 있다면 나머지는 자동적으로 채워지는 것이 보장되기 때문이다.
프로그램 동작
아래와 같이 `N = 11`, `M = 3`, 가로등 위치는 `3, 7, 9` 로 들어온다고 가정해보자. ▼
가장 처음 간격부터 가장 큰 간격을 찾아주면 된다.
하지만 주의할 점이 하나 있다.
바로 가로등이 좌, 우를 모두 비춘다는 것이다.
맨 앞과 맨 뒤의 간격은 가로등의 좌, 혹은 우만 사용하기 때문에 하나의 가로등 높이가 그만큼 높아져야 채울 수 있다.
아래와 같은 경우, 가장 왼쪽 간격을 채우기 위해서는 가로등 높이가 최소 3이 되어야 하고, 오른쪽 간격을 채우기 위해서는 최소 2의 높이가 필요하다. ▼
하지만 가로등과 가로등 사이의 간격은 하나의 가로등이 해당 간격을 전부 부담하지 않아도 된다.
3과 7 사이의 간격은 4지만, 두 개의 가로등이 왼쪽과 오른쪽으로 나누어 비추기 때문에 높이가 2만 되어도 해당 간격을 채울 수 있다.
똑같이 7과 9 사이의 간격은 높이가 1만 되어도 채울 수 있다. ▼
그렇기에 각각의 간격은, `3, 4, 2, 2`로 보는게 아니라 `3, 2, 1, 2`로 보며 가장 넓은 간격이 3이기에 높이는 최소한 3이 되어야 전체를 다 비출 수 있다.
C++ 코드
#include <iostream>
#include <cmath>
using namespace std;
int N, M, prv, tmp, maxVal;
int main() {
cin >> N >> M;
for (int i = 0; i < M; i++) {
cin >> tmp;
if (i == 0)
maxVal = (maxVal < tmp - prv) ? tmp - prv : maxVal;
else
maxVal = (maxVal < ceil(double(tmp - prv) / 2)) ? ceil(double(tmp - prv) / 2) : maxVal;
prv = tmp;
}
maxVal = (maxVal < N - prv) ? N - prv : maxVal;
cout << maxVal;
}
높이는 정수만 되기 때문에, 2로 나눈 값을 정수로 올림을 해주어야 한다.
이때 `int / int`를 하면 자동으로 `int`가 되니 형변환을 해서 나눠야 한다.
'Algorithm > PS' 카테고리의 다른 글
백준 19941번 햄버거 분배 - C++ (0) | 2024.06.06 |
---|---|
백준 1515번 수 이어 쓰기 - C++ (0) | 2024.06.05 |
백준 10341번 줄세우기 - C++ (0) | 2024.05.25 |
백준 9655번 돌 게임 - C++ (0) | 2024.05.25 |
백준 1157번 단어 공부 - SWIFT, C++ (0) | 2024.05.23 |