문제 풀이/소프티어

[소프티어] 진정한 효도(JAVA)

27200 2025. 3. 20. 17:32

문제

https://softeer.ai/practice/7374


풀이(40분)

import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int[][] grid = new int[3][3];

        // 입력 받기
        for (int i = 0; i < 3; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < 3; j++) {
                grid[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int minCost = Integer.MAX_VALUE;

        // 가로, 세로 3칸씩 검사
        for (int i = 0; i < 3; i++) {
            minCost = Math.min(minCost, calculateCost(grid, i, 0, i, 2)); // 가로
            minCost = Math.min(minCost, calculateCost(grid, 0, i, 2, i)); // 세로
        }

        System.out.println(minCost);
    }

    // 주어진 3칸의 숫자를 같은 값으로 만드는 비용 계산
    static int calculateCost(int[][] grid, int x1, int y1, int x2, int y2) {
        int[] values = new int[3];
        int index = 0;

        // 3개의 값을 배열에 저장
        for (int i = x1; i <= x2; i++) {
            for (int j = y1; j <= y2; j++) {
                values[index++] = grid[i][j];
            }
        }

        Arrays.sort(values);

        int minCost = Integer.MAX_VALUE;

        // 1, 2, 3 중 하나로 변환할 때 비용 계산
        for (int target = 1; target <= 3; target++) {
            int cost = 0;
            for (int i = 0; i < 3; i++) {
                cost += Math.abs(values[i] - target);
            }
            minCost = Math.min(minCost, cost);
        }

        return minCost;
    }
}

문제 풀이 전략

 

사실 간단한 코드다.

농장의 크기가 3x3으로 지정되어 있고, 입력도 1~3까지이기 때문에 브루트포스로 모두 구해보면 되는 것이다.

정리하자면 모든 행과 열에서 1,2,3중 어떤 값으로 변환했을 때 최소가 되는지에 대해 27가지를 모두 저장한 뒤 최소를 뽑아내면 된다.

 

하지만 문제를 푸는 데 있어 40분이나 소요된 것은 그 외에 조건이 확장된다면 어떻게 해야 할지를 고민해 보았다.

대표적으로 평균값과 중앙값 사이에서 고민을 했다.

일반적으로 숫자를 맞추라는 것은 평균(반올림, 올림, 내림 등을 거쳐)을 구한 뒤 이에 맞추면 된다. 문제의 1,1,3을 보면 1로 맞추어 2로 변경하는 것이 최솟값이 된다. 즉, 평균값이 아닌(여기서 평균은 반올림을 했다.) 중앙값을 구하라는 것이다.

그럼 평균(내림)을 하면 되는 거 아닐까?라는 고민도 해보았지만 반례가 존재했다.

중앙값은 완벽한가에 대해서도 길이가 짝수라면?이라는 고민이 되었다.

즉, 동일하게 1~3의 숫자만 입력된다!라고 한다면 단순히 1~3을 모두 해보는 것이 더 좋을 수도 있다는 뜻이다.

 

수학적으로 정확한 결론은 못 내렸지만 조건의 확장을 고민해 보고, 가끔은 단순한 검사가 더 효율적일 수도 있다는 결론을 얻을 수 있었다.