코딩테스트/백준

14500번 - 테트로미노

feel2 2023. 3. 12. 08:39
반응형

1. 문제 정의

 

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.

  • 정사각형은 서로 겹치면 안 된다.
  • 도형은 모두 연결되어 있어야 한다.
  • 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.

정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.

아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.

테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.

테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.

 -입력-

첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)

둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.

 -출력-

첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.

 

2. 문제 접근

dfs로 접근하여 모든 경우를 완전탐색한다면 풀 수 있을 것 같다고 생각하여 그렇게 했다.

 

3. 문제 풀이

1. 각 입력값을 받는다.

2. dfs 함수를 실행한다.

 

4. 코드

package sw역량문제;

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

public class 테트로미노 {
    static StringBuilder sb = new StringBuilder();
    static int N, M, max_value;
    static int[][] matrix;
    static boolean[][] visited;
    static int[][] dir = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    static void input() {
        FastReader scan = new FastReader();
        N = scan.nextInt();
        M = scan.nextInt();
        matrix = new int[N][M];
        visited = new boolean[N][M];

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                matrix[i][j] = scan.nextInt();
            }
        }

    }

    // Recursive Function (재귀 함수)
    static void dfs(int k, int x, int y, int sum) {
        if (k == 3) {

            max_value = Math.max(max_value, sum);


        } else {
            for (int d = 0; d < 4; d++) {
                int nx = x + dir[d][0];
                int ny = y + dir[d][1];

                // 배열 범위 벗어나면 패스
                if (nx < 0 || ny < 0 || N <= nx || M <= ny) continue;
                // 이미 방문한 경우 패스
                if (visited[nx][ny]) continue;
                if (k == 1) {
                    visited[nx][ny] = true;
                    dfs(k + 1, x, y, sum + matrix[nx][ny]);
                    visited[nx][ny] = false;
                }
                visited[nx][ny] = true;
                dfs(k + 1, nx, ny, sum + matrix[nx][ny]);
                visited[nx][ny] = false;
            }
        }
    }

    public static void main(String[] args) {
        input();
        max_value = Integer.MIN_VALUE;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                visited[i][j] = true;
                dfs(0, i, j, matrix[i][j]);
                visited[i][j] = false;
            }
        }

        System.out.println(max_value);
    }


    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws FileNotFoundException {
            br = new BufferedReader(new FileReader(new File(s)));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

 

5. 회고

테트로미노 중 ㅗ 모양은 일반 dfs로 모양을 만들기 힘들다. 그래서 중간에 한번 더 dfs 를 해주어 저 모양을 만들 수 있게 해주었다. 

반응형

'코딩테스트 > 백준' 카테고리의 다른 글

14888번 - 연산자 끼워넣기  (1) 2023.03.12
14502번 - 연구소  (1) 2023.03.12
13458번 - 시험 감독  (0) 2023.03.04
3190번 - 뱀  (0) 2023.03.04
12100번 - 2048 (Easy)  (0) 2023.03.04