마인크래프트 하는 것처럼 모든 격자를 탐색하면서 현재 격자와 주변 격자에서의 땅 높이를 맞추어나가는 방식으로는 풀 수 없을 것이라는 생각이 들었다.
(현재 인벤토리에 있는 블럭의 수 + 땅에 있는 블럭의 수) = 내가 사용가능한 블럭의 수
라는 점을 사용해서 땅의 높이가 될 수 있는 최댓값을 찾고, 높이를 줄여나가면서 소요시간의 최솟값을 계산하도록 코드를 작성했다.
package Baekjoon;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ18111 {
/*
인벤토리에 가지고 있는 블록과 맵에 있는 블록의 합계를 구해서
맵 격자 수만큼 나눠서 쌓는다
높이를 1씩 줄여가면서 해당 높이에서 소요되는 시간을 구한다
*/
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());
long total = b;
int[][] map = new int[n][m];
for(int i = 0; i < n; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0; j < m; j++){
map[i][j] = Integer.parseInt(st.nextToken());
total += map[i][j];
}
}
int height = (int) (total / (n*m)); //격자 하나당 가질 수 있는 최대 높이
if (height > 256) height = 256;
int time = Integer.MAX_VALUE;
int answerHeight = height;
while(height >= 0){
int curTime = 0;
//현재 높이에서의 시간 구하기
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(map[i][j] <= height) curTime += (height - map[i][j]);
else curTime += ( 2 * (map[i][j] - height));
}
}
if(curTime < time){
time = curTime;
answerHeight = height;
}
height--;
}
System.out.println(time + " " + answerHeight);
}
}