본문 바로가기
백준

[BOJ][Java]백준 14500번: 테트로미노

by 너츠너츠 2022. 12. 29.

문제 설명

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

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

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

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

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

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

 

문제 풀이

이 문제는 어떻게 효율적으로 풀가 고민하게 되면 늪에 빠지게 되는 문제라고 생각됩니다.

각 블록의 형태도 다르고 대칭성이 없는 블록, 회전해도 똑같은 블록이 존재하기에 각 블록마다 케이스를 잡고 브루트포스를 통해 구현해주면 쉽게 해결되는 문제입니다.

 

각 블록의 케이스는 어떻게 구하든 N, M만큼 반복문을 돌게되면 모든 대칭, 회전한 케이스까지 검토할 수 있으므로 자신이 편한대로 케이스를 잡아주시면 됩니다.

풀이 코드

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

public class Main {

    private static int N, M;
    private static int[][] map;
    private static int[][][] blockCase = new int[][][]{
            {{0, 0}, {0, 1}, {1, 0}, {1, 1}}, // 네모 블럭
            {{0, 0}, {0, 1}, {0, 2}, {0, 3}}, // l블록 가로배치
            {{0, 0}, {1, 0}, {2, 0}, {3, 0}}, // l블록 세로 배치
            {{0, 0}, {0, 1}, {0, 2}, {1, 1}}, // ㅜ블록 배치
            {{0, 0}, {0, 1}, {0, 2}, {-1, 1}}, // ㅗ블록 배치
            {{0, 0}, {1, 0}, {2, 0}, {1, 1}}, // ㅏ블록 배치
            {{0, 0}, {1, 0}, {2, 0}, {1, -1}}, // ㅓ블록 배치
            {{0, 0}, {1, 0}, {1, 1}, {2, 1}}, // 4번째 블록 정배치
            {{0, 0}, {1, 0}, {1, -1}, {2, -1}}, // 4번째 블록 정배치 대칭
            {{0, 0}, {0, -1}, {1, -1}, {1, -2}}, // 4번째 블록 우측 1회전
            {{0, 0}, {0, 1}, {1, 1}, {1, 2}}, // 4번째 블록 우측 1회전 대칭
            {{0, 0}, {1, 0}, {2, 0}, {2, 1}}, // L블록 배치
            {{0, 0}, {1, 0}, {2, 0}, {2, -1}}, // L블록 대칭 배치
            {{0, 0}, {1, 0}, {0, 1}, {0, 2}}, // ㄱ블록(가로 긴 버전) 대칭 배치
            {{0, 0}, {0, 1}, {0, 2}, {1, 2}}, // ㄱ블록(가로 긴 버전) 배치
            {{0, 0}, {0, 1}, {1, 1}, {2, 1}}, // ㄱ블룩(세로 긴 버전) 배치
            {{0, 0}, {0, 1}, {1, 0}, {2, 0}}, // ㄱ블록(세로 긴 버전) 대칭 배치
            {{0, 0}, {1, 0}, {1, 1}, {1, 2}}, // ㄴ블록 배치
            {{1, 0}, {1, 1}, {1, 2}, {0, 2}} // ㄴ블록 대칭 배치
    };

    public static void main(String[] args) throws IOException {
        input();
        solve();
    }

    private static void solve() {
        int ans = 0;

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                for (int k = 0; k < blockCase.length; k++) {
                    int sum = 0;
                    boolean isBlock = true;
                    for (int t = 0; t < 4; t++) {
                        int bx = i + blockCase[k][t][0]; // 체크하고자 하는 블록의 x
                        int by = j + blockCase[k][t][1]; // 체크하고자 하는 블록의 y

                        if (bx < 0 || by < 0 || bx >= N || by >= M) {
                            isBlock = false;
                            break;
                        }

                        sum += map[bx][by];
                    }

                    if (!isBlock) continue;

                    ans = Math.max(ans, sum);
                }
            }
        }

        System.out.println(ans);
    }

    private static void input() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        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());
            }
        }
    }
}

 

<출처>

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

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

www.acmicpc.net

 

반응형

댓글