백준 알고리즘/Java

[백준] 14889. 스타트와 링크 - Java

리버🐦‍🔥 2025. 4. 22. 18:11

https://www.acmicpc.net/problem/14889

 

⭐️ 중요 포인트

1. isChecked[]로 현재 선택된 팀원 저장하며 cnt == N/2가 됐을 때 해당 팀원으로 계산

2. 꼭 하나의 재귀가 끝나면 isChecked[i] = false를 통해 선택했던 팀원 해제해주기

3. (isChecked[i] && isChecked[j])를 통해 start팀에 선택된 팀원과 (!isChecked[i] && !isChecked[j]) start팀에 선택되지 않은 팀원(= link 팀)의 점수를 각각 계산할 것

 

<아래는 실제 재귀가 반복될 때 그려지는 트리 구조>

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

public class P14889 {

    static BufferedReader br;
    static BufferedWriter bw;
    static StringTokenizer st;

    static int N;
    static int[][] S;

    static int totalScore;
    static boolean[] isChecked;
    static int answer;

    static void init() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        bw = new BufferedWriter(new OutputStreamWriter(System.out));

        N = Integer.parseInt(br.readLine());
        S = new int[N][N];

        totalScore = 0;
        isChecked = new boolean[N];
        answer = Integer.MAX_VALUE;

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                S[i][j] = Integer.parseInt(st.nextToken());
                totalScore += S[i][j];
            }
        }
    }

    static int calcScoreGap() throws IOException {
        int startScore = 0;
        int linkScore = 0;
        for (int i = 0; i < N - 1; i++) {
            for (int j = i + 1; j < N; j++) {
                if (isChecked[i] && isChecked[j]) {
                    startScore += S[i][j] + S[j][i];
                }
                if (!isChecked[i] && !isChecked[j]) {
                    linkScore += S[i][j] + S[j][i];
                }
            }
        }

//        System.out.println(Math.abs(startScore - linkScore));

        return Math.abs(startScore - linkScore);
    }

    static void recursion(int cnt, int idx) throws IOException {

        // 정확히 팀을 반으로 나눴을 때 탈출
        if (cnt == N / 2) {
            // 점수 계산
            answer = Math.min(answer, calcScoreGap());
            return;
        }

        for (int i = idx; i < N; i++) {
            if (!isChecked[i]) {
                isChecked[i] = true;
                recursion(cnt + 1, i);
                isChecked[i] = false;
            }
        }


    }

    public static void main(String[] args) throws IOException {
        init();

        recursion(0, 0);

        bw.write(String.valueOf(answer));

        bw.flush();
        bw.close();
        br.close();
    }
}