Algorithm/Problem Solving

[SWEA/SW Test 샘플] 1767. 프로세서 연결하기 - JAVA 자바

gangintheremark 2024. 2. 21. 23:49
728x90
  • 129ms
  • 구현 DFS

최대한 많은 코어를 전원에 연결할 경우, 필요한 전선 길이의 합의 최소를 구하는 문제이다. 단, 전선끼리 교차할 수 없다.

 

(x,y) 좌표에서의 코어가 (x, 0), (x, n-1), (0, y), (n-1, y) 까지 전선을 설치할 수 있는지, 설치할 수 있는 경우에서 전선의 길이가 최소로 되는 방향으로 설치할 수 있도록 한다.

 

1. 가장자리가 아닌 코어들의 좌표를 리스트에 저장

2. 코어 리스트를 하나씩 돌며 상하좌우 탐색하며 전선을 설치할 수 있는 방향을 찾은 후 방문처리하며 DFS 탐색 진행

    2-1. 방문처리하며 진행하다가 중간에 끊겨 해당 방향으로 전선을 설치할 수 없다면 코어의 좌표까지 다시 되돌아가며 방문처리 해제

3. 전선을 설치할 수 있는 방향이 있다면 전선 길이의 합에 + 후 다음 인덱스 상하좌우 탐색 → 2번으로

4. 모든 코어를 다 확인했다면 전선을 연결한 코어의 최대 & 전선 합의 최소가 되는지 구한다.

5. 백트래킹

 

# 소스코드

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;


public class Solution {
    static List<int[]> cores = new ArrayList<int[]>();
    static int n, max = 0, minLen = Integer.MAX_VALUE;
    static boolean[][] visited;
    static int[] dx = { 1, -1, 0, 0 };
    static int[] dy = { 0, 0, 1, -1 };

    // 해당 방향으로 전선을 이을 수 있는지 체크 후 길이 출력
    public static int calcLen(int x, int y, int d) {
        int len = 0;
        int tmpx = x, tmpy = y;
        while (true) {
            tmpx += dx[d];
            tmpy += dy[d];
            if (tmpx >= 0 && tmpx < n && tmpy>= 0 && tmpy < n) {
                if (!visited[tmpx][tmpy]) {
                    len++;
                    visited[tmpx][tmpy] = true;
                } else {
                    // 중간에 끊겼다면 지금까지 방문표시한 것들 해제
                    while(true) {
                        tmpx -= dx[d];
                        tmpy -= dy[d];
                        if(tmpx == x && tmpy == y) break;
                        visited[tmpx][tmpy] = false;
                    }
                    return -1;
                }
            } else
                break;
        }
        return len;
    }

    public static void backtrace(int x, int y, int d) {
        while (true) {
            x += dx[d];
            y += dy[d];
            if (x >= 0 && x < n && y >= 0 && y < n)
                visited[x][y] = false;
            else
                break;
        }
    }

    public static void dfs(int index, int count, int length) {
        if (index == cores.size()) {
            if (max < count) {
                minLen = length;
                max = count;
            } else if (max == count) {
                minLen = Math.min(minLen, length);
            }
            return;
        }
        for (int d = 0; d < 4; d++) {
            int nx = cores.get(index)[0];
            int ny = cores.get(index)[1];

            int len = calcLen(nx, ny, d);
            if (len == -1) {
                continue; // 이 방향은 안돼
            } else {
                // 전선을 포함한 경우
                dfs(index + 1, count + 1, length + len);
                backtrace(nx, ny, d);

            }
        }
        // 전선을 포함하지 않은 경우
        dfs(index + 1, count, length);
    }

    public static void main(String[] args) throws NumberFormatException, IOException {
        System.setIn(new FileInputStream("sample_input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());

        for (int t = 1; t <= T; t++) {
            cores.clear();
            n = Integer.parseInt(br.readLine());
            visited = new boolean[n][n];
            minLen = Integer.MAX_VALUE;
            max = 0;
            for (int i = 0; i < n; i++) {
                st = new StringTokenizer(br.readLine());
                for (int j = 0; j < n; j++) {
                    if (Integer.parseInt(st.nextToken()) == 1) {
                        if (i != 0 && i != n - 1 && j != 0 && j != n - 1)
                            cores.add(new int[] { i, j }); // 가장자리 코어가 아니라면 코어 리스트에 저장
                        visited[i][j] = true;
                    }
                }
            }

            dfs(0, 0, 0);
            sb.append('#').append(t).append(' ').append(minLen).append('\n');
        }
        System.out.println(sb);
    }
}
728x90