본문 바로가기

알고리즘

백준 - 14500 테트로미노(Java)

구현 문제입니다.

 

원본, 대칭, 회전을 한 테트로미노 모양에 따라 변화되는 좌표를 전부 입력한 뒤, 계산을 하는 방법으로 구현했습니다.

 

[구현 코드]

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

public class Main {
    private static final int TETROMINO_COUNT = 5;
    private static final int ROTATION_COUNT = 8; // 정방향을 제외한 최대 회전 및 대칭 개수

    private static class Point {
        int x, y;

        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    // 네 개의 도형으로 이뤄졌기 때문에, 시점을 제외하고 세 개의 좌표를 가짐
    private static class Tetromino {
        Point p1, p2, p3;

        Tetromino(Point p1, Point p2, Point p3) {
            this.p1 = p1;
            this.p2 = p2;
            this.p3 = p3;
        }

        private List<Point> getPoints(){
            return List.of(p1, p2, p3);
        }
    }

    // 도형
    private static class TetrominoRotations {
        Tetromino[][] diagram = new Tetromino[TETROMINO_COUNT][ROTATION_COUNT];
		
        // 아래 주석의 *의 모양일 때 회전, 대칭 이동을 하면 바뀔수 있는 좌표의 이동 값입니다.
        TetrominoRotations() {
            /*
            	****
            */
            diagram[0][0] = new Tetromino(new Point(0, 1), new Point(0, 2), new Point(0, 3));
            diagram[0][1] = new Tetromino(new Point(1, 0), new Point(2, 0), new Point(3, 0));

            /*
            	**
             	**
            */
            diagram[1][0] = new Tetromino(new Point(0, 1), new Point(1, 0), new Point(1, 1));
			
            /*
            	***
                *
            */
            diagram[2][0] = new Tetromino(new Point(1, 0), new Point(2, 0), new Point(2, 1));
            diagram[2][1] = new Tetromino(new Point(1, 0), new Point(2, 0), new Point(2, -1));
            diagram[2][2] = new Tetromino(new Point(0, 1), new Point(1, 0), new Point(2, 0));
            diagram[2][3] = new Tetromino(new Point(0, -1), new Point(1, 0), new Point(2, 0));
            diagram[2][4] = new Tetromino(new Point(-1, 0), new Point(-1, -1), new Point(-1, -2));
            diagram[2][5] = new Tetromino(new Point(-1, 0), new Point(-1, 1), new Point(-1, 2));
            diagram[2][6] = new Tetromino(new Point(1, 0), new Point(1, 1), new Point(1, 2));
            diagram[2][7] = new Tetromino(new Point(1, 0), new Point(1, -1), new Point(1, -2));

            /*
            	**
                 **
            */
            diagram[3][0] = new Tetromino(new Point(1, 0), new Point(1, 1), new Point(2, 1));
            diagram[3][1] = new Tetromino(new Point(1, 0), new Point(1, -1), new Point(2, -1));
            diagram[3][2] = new Tetromino(new Point(0, -1), new Point(1, 0), new Point(1, 1));
            diagram[3][3] = new Tetromino(new Point(0, 1), new Point(1, 0), new Point(1, -1));

            /*
            	***
                 *
            */
            diagram[4][0] = new Tetromino(new Point(-1, 0), new Point(0, 1), new Point(0, -1));
            diagram[4][1] = new Tetromino(new Point(1, 0), new Point(0, 1), new Point(0, -1));
            diagram[4][2] = new Tetromino(new Point(0, -1), new Point(-1, 0), new Point(1, 0));
            diagram[4][3] = new Tetromino(new Point(0, 1), new Point(-1, 0), new Point(1, 0));
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer stz = new StringTokenizer(br.readLine(), " ");

        TetrominoRotations tetrominoRotations = new TetrominoRotations();

        int n = Integer.parseInt(stz.nextToken());
        int m = Integer.parseInt(stz.nextToken());

        int[][] map = new int[n][m];
        for (int i = 0; i < n; i++) {
            stz = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < m; j++) {
                map[i][j] = Integer.parseInt(stz.nextToken());
            }
        }

        int answer = 0;
        for (int x = 0; x < n; x++) {
            for (int y = 0; y < m; y++) {
                for(int t =0; t<TETROMINO_COUNT; t++){
                    Rotation : for(int r = 0; r<ROTATION_COUNT; r++){
                        Tetromino tetromino = tetrominoRotations.diagram[t][r];
                        if(tetromino == null) continue;

                        int sum = map[x][y]; // 해당 모양의 합을 구함
                        List<Point> points = tetromino.getPoints();
                        for(Point p : points){
                            int nx = x + p.x;
                            int ny = y + p.y;

                            if(!inRange(nx, ny, n, m)) continue Rotation;

                            sum += map[nx][ny];
                        }

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

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

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

    private static boolean inRange(int x, int y, int n, int m) {
        return x >= 0 && y >= 0 && x < n && y < m;
    }
}