본문 바로가기

삼성전자 알고리즘/백준온라인

3. 2805 나무 자르기

원본 출처 : 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