원본 출처 : https://www.acmicpc.net/problem/2805
2805번: 나무 자르기
문제 상근이는 나무 M미터가 필요하다. 근처에 나무를 구입할 곳이 모두 망해버렸기 때문에, 정부에 벌목 허가를 요청했다. 정부는 상근이네 집 근처의 나무 한 줄에 대한 벌목 허가를 내주었고, 상근이는 새로 구입한 목재절단기을 이용해서 나무를 구할것이다. 목재절단기는 다음과 같이 동작한다. 먼저, 상근이는 절단기에 높이 H를 지정해야 한다. 높이를 지정하면 톱날이 땅으로부터 H미터 위로 올라간다. 그 다음, 한 줄에 연속해있는 나무를 모두 절단해버린다. 따
www.acmicpc.net
문제 풀이 :
#include <stdio.h>
#define MAX 1000010
int N, M;
int arr[MAX];//나무의 최대 수
void quick_sort(int s, int e) {
int L, T, P = e, temp;
if (s >= e) return; //종료 조건
for (L = s, T = s; L < e; L++) {
if (arr[L] < arr[P]) {
if (L != T) { temp = arr[L]; arr[L] = arr[T]; arr[T] = temp; }
T++;
}
}
if (P != T) { temp = arr[P]; arr[P] = arr[T]; arr[T] = temp; }
quick_sort(s, T - 1);
quick_sort(T + 1, e);
}
long long solve(int m) {
long long sum_tree = 0;
for (int i = 0; i < N; i++) {
if (arr[i] > m) {
sum_tree += arr[i] - m;
}
}
return sum_tree;
}
int main() {
int i;
long long m, s, e, sol = 0;
scanf("%d", &N); //나무의 수
scanf("%d", &M); //나무의 길이
for (i = 0; i < N; i++) {
scanf("%d", &arr[i]);
}
quick_sort(0, N - 1);
s = 0; //s는 가장 작은 수
e = arr[N - 1]; //e는 가장 큰 수
scanf("%d", &M);
while (s <= e) {
m = (s + e) / 2; //상한가를 mid로 계산
if (solve(m) < M) {
//H가 높으면 줄여본다.
e = m - 1;
}
else if (solve(m) >= M) {
//H가 낮으면 높혀본다
sol = m;
s = m + 1;
}
}
printf("%lld\n", sol);
return 0;
}
예산 문제와 같은 개념의 문제이다. 예산은 최대한 많은 예산을 줘야 했고 나무는 적어도 얼마나 들고 가면 되냐 하는 문제이다. 입력되는 값이 크기 때문에 long long 을 써주어야 한다.
'삼성전자 알고리즘 > 백준온라인' 카테고리의 다른 글
6. 3653 영화 수집 (0) | 2019.06.28 |
---|---|
5. 10755 컴퓨터실 (0) | 2019.06.28 |
4. 11066 파일 합치기 [힙] (0) | 2019.06.16 |
2. 2961 도영이가 만든 맛있는 음식 (0) | 2019.05.09 |
1. 1920 수 찾기 (0) | 2019.05.07 |