본문 바로가기

CodingTEST

[백준 14500] 테트로미노(JAVA)

반응형

백준 14500번 문제 - 테트로미노

 

14500번: 테트로미노

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

www.acmicpc.net


문제 분석 

 

 

  • 블록은 5가지가 있다.
    • 회전, 대칭 가능
  • N x M인 판(테트로미노)가 있다. 각 칸에는 숫자가 적혀있다.
  • 블록을 둬서 블록이 차지하는 칸의 합이 결과 값이라고 할 때, 해당 테트로미노에서 얻을 수 있는 가장 큰 결과 값을 출력해라.

 

해결 포인트

 

  • 완전 탐색
  • 블록 클래스 구현
    • 블록의 첫번째 칸을 0,0이라했을 때 칸 4개의 x의 변화 y의 변화를 저장한다.
    • ex) 가로로 긴 배열은 (0,0) (1,0) (2,0) (3,0) 4개의 칸이 있다. 
      이 때 dx = {0,1,2,3} | dy = {0,0,0,0} 이다.
  • 판의 (0,0)부터 (N-1, M-1) 칸까지 해당 칸이 시작점일 경우, 해당 블록이 낼 수 있는 최대 결과 값을 알아낸다.
  • 블록의 최댓값은 해당 블록의 getCount 함수로 구현하였다.
    • 인자 값 : 시작 x, 시작 y
    • 회전 확인 : 이 때 모든 칸의 값을 합쳐서 구한다.
      • ndx, ndy는 회전 설정 값이다.
      • int nx = sx + dx[j] * ndx[i]
      • int ny = sy + dy[j] * ndy[i] 
    • 대칭 확인 : 대칭한 값은 초기 칸 변화를 dx, dy를 바꿔서 설정한다.
      • ndx, ndy는 회전 설정 값이다.
      • int nx = sx + dy[j] * ndx[i]
      • int ny = sy + dx[j] * ndy[i] 
  • 알아낸 후, 현재 최댓값과 비교 후 더 크면 변경한다.

 

코드

 

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

public class Main {
    public static int[][] nums;
    public static int N, M;

    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 st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

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

        ArrayList<Block> blocks = new ArrayList<>();

        blocks.add(new Block(new int[]{0, 1, 2, 3}, new int[]{0, 0, 0, 0}));
        blocks.add(new Block(new int[]{0, 1, 2, 2}, new int[]{0, 0, 0, -1}));
        blocks.add(new Block(new int[]{0, 0, 1, 1}, new int[]{0, 1, 0, 1}));
        blocks.add(new Block(new int[]{0, 1, 1, 2}, new int[]{0, 0, -1, -1}));
        blocks.add(new Block(new int[]{0, 1, 2, 1}, new int[]{0, 0, 0, 1}));

        int max = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                for (Block block : blocks) {
                    max = Math.max(max, block.getCount(j, i));
                }
            }
        }

        bw.write(max + "\n");

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

    public static class Block {
        int [] dx;
        int [] dy;

        public Block(int [] dx, int [] dy) {
            this.dx = dx;
            this.dy = dy;
        }

        public int getCount(int sx, int sy) {
            int maxCount = 0;
            int count;

            int []ndx = {1,1,-1,-1};
            int []ndy = {1,-1,1,-1};

            for (int i = 0; i < 4; i++) {
                count = 0;
                for (int j = 0; j < 4; j++) {
                    int nx = sx + dx[j] * ndx[i];
                    int ny = sy + dy[j] * ndy[i];
                    if (!checkRound(nx, ny)) {
                        continue;
                    }
                    count += nums[ny][nx];
                }
                maxCount = Math.max(maxCount, count);
            }

            for (int i = 0; i < 4; i++) {
                count = 0;
                for (int j = 0; j < 4; j++) {
                    int nx = sx + dy[j] * ndx[i];
                    int ny = sy + dx[j] * ndy[i];
                    if (!checkRound(nx, ny)) {
                        continue;
                    }
                    count += nums[ny][nx];
                }
                maxCount = Math.max(maxCount, count);
            }

            return maxCount;
        }
    }

    public static boolean checkRound(int x, int y) {
        return x >= 0 && y >= 0 && x < M && y < N;
    }
}

 

반응형

'CodingTEST' 카테고리의 다른 글

[프로그래머스] 전화번호 목록 (JAVA)  (0) 2024.01.13
[백준 11725] 트리의 부모 찾기(JAVA)  (0) 2024.01.12
[백준 9019] DSLR (JAVA)  (1) 2024.01.06
[백준 5430] AC (JAVA)  (1) 2024.01.06
[백준 1107] 리모컨(JAVA)  (1) 2024.01.02