

내가 생각했을때 문제에서 원하는부분
첫째 줄에 N, M, B가 주어진다. (1 ≤ M, N ≤ 500, 0 ≤ B ≤ 6.4 × 107)
둘째 줄부터 N개의 줄에 각각 M개의 정수로 땅의 높이가 주어진다.
(i + 2)번째 줄의 (j + 1)번째 수는 좌표 (i, j)에서의 땅의 높이를 나타낸다.
땅의 높이는 256보다 작거나 같은 자연수 또는 0이다.
첫째 줄에 땅을 고르는 데 걸리는 시간과 땅의 높이를 출력하시오.
답이 여러 개 있다면 그중에서 땅의 높이가 가장 높은 것을 출력하시오.
내가 이 문제를 보고 생각해본 부분
먼저 입력으로 땅 크기 N, M과 초기 인벤토리 블록 수 B를 받는다.
다음으로 땅 각 칸의 높이를 2차원 배열에 저장하면서 최솟값과 최댓값을 찾아 높이 조절 범위를 설정한다.
가능한 땅 높이 후보인 minHeight부터 maxHeight까지 모두 시도하면서, 각각의 후보 높이에 맞추기 위한 작업 시간을 계산한다.
각 칸의 현재 높이와 후보 높이의 차이를 계산하여 다음을 처리한다:
높이가 더 높으면 블록을 제거해 인벤토리에 넣고 2초 걸림
높이가 더 낮으면 인벤토리에서 블록 꺼내 쌓아 1초 걸림
작업 중 인벤토리 블록 수가 음수가 되면 불가능한 경우이므로 그 후보 높이는 건너뛴다.
가능한 후보 높이 중 작업 시간이 가장 적은 경우를 기록하고, 시간이 같으면 더 높은 땅 높이를 선택한다.
반복이 끝나면 최소 시간을 출력하고, 그때의 땅 높이를 출력한다.
이 문제는 모든 후보 높이를 브루트 포스로 탐색하는 문제로, 입력 조건(N ≤ 500) 내에서 충분히 동작한다.
코드로 구현
package baekjoon.baekjoon_33;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// 백준 18111번 문제
public class Main1329 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
int[][] land = new int[N][M];
int minHeight = 256;
int maxHeight = 0;
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
land[i][j] = Integer.parseInt(st.nextToken());
if (land[i][j] < minHeight) minHeight = land[i][j];
if (land[i][j] > maxHeight) maxHeight = land[i][j];
}
}
int resultTime = Integer.MAX_VALUE;
int resultHeight = 0;
// 가능한 높이 범위 내에서 모두 검사
for (int h = minHeight; h <= maxHeight; h++) {
int time = 0;
int inventory = B;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
int diff = land[i][j] - h;
if (diff > 0) {
// 땅에서 블록 제거 (2초, 블록 인벤토리에 추가)
time += diff * 2;
inventory += diff;
} else if (diff < 0) {
// 인벤토리에서 블록 꺼내서 쌓기 (1초)
time += (-diff);
inventory -= (-diff);
}
}
}
// 인벤토리 블록이 음수이면 불가능한 높이
if (inventory < 0)
continue;
// 최소 시간 갱신, 동일하면 더 높은 높이 선택
if (time < resultTime || (time == resultTime && h > resultHeight)) {
resultTime = time;
resultHeight = h;
}
}
System.out.println(resultTime + " " + resultHeight);
br.close();
}
}
코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.