문제 링크: https://www.acmicpc.net/problem/14500

 

14500번: 테트로미노

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

www.acmicpc.net

▶문제

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

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

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

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

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

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


▶입력

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

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


▶출력

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


▶해설

단순한?? 구현 문제입니다. 블럭 하나당 case를 나눠서 모든 부분을 탐색하면 됩니다.

 

주의점1: 배열의 크기 설정을 생각해줘야 합니다. 

 

예를 들어서 가로 4칸의 직선의 경우 0,0에서 왼쪽 부분이 시작이라면 0,3까지의 합입니다. 하지만 오른쪽 부분이 0,0이라면 왼쪽 부분은 0,-3으로 오류가 발생합니다.

 

따라서 배열의 크기를 입력받은 숫자보다 6이 더 크게 설정해줘야 합니다. 

 

주의점2: 직선 모양(가로 세로), 정사각형(1개), ㄴ모양(밑이 2일 때 대칭 4개 + 밑이 3일 때 대칭 4개 총 8개),

ㄱㄴ모양(대칭해서 4개), ㅗ모양(대칭해서 4개) ㄴ 모양의 경우 밑변을 설정해서 8개의 case로 나눠야 합니다.

 

전체 코드

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


public class Main {

    static int [][]map;
    static int max;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] s = br.readLine().split(" ");

        int n = Integer.parseInt(s[0]);
        int m = Integer.parseInt(s[1]);

        map = new int[n+6][m+6];

        for(int i=3; i<n+3; i++){
            String[] s1 = br.readLine().split(" ");
            for(int j=3; j<m+3; j++){
                map[i][j] = Integer.parseInt(s1[j-3]);
            }
        }

        for(int i=0; i<n+3; i++){
            for(int j=0; j<m+3; j++){
                solve(i,j);
            }
        }

        System.out.println(max);
    }

    private static void solve(int a, int b){
        case0(a, b);
        case1(a, b);
        case2(a, b);
        case3(a, b);
        case4(a, b);
    }

    private static void case0(int a, int b) {
        int sum=0;
        sum += map[a][b];
        sum += map[a +1][b];
        sum += map[a +2][b];
        sum += map[a +3][b];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b];
        sum += map[a][b +1];
        sum += map[a][b +2];
        sum += map[a][b +3];
        if(max<sum){
            max = sum;
        }
    }

    private static void case1(int a, int b) {
        int sum;
        sum=0;
        sum += map[a][b];
        sum += map[a+1][b];
        sum += map[a+1][b+1];
        sum += map[a][b+1];
        if(max<sum){
            max = sum;
        }
    }

    private static void case2(int a, int b) {
        int sum;
        sum=0;
        sum += map[a][b];
        sum += map[a +1][b];
        sum += map[a +2][b];
        sum += map[a +2][b +1];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b +1];
        sum += map[a +1][b +1];
        sum += map[a +2][b +1];
        sum += map[a +2][b];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b];
        sum += map[a +1][b];
        sum += map[a][b +1];
        sum += map[a][b +2];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b];
        sum += map[a +1][b +2];
        sum += map[a][b +1];
        sum += map[a][b +2];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b];
        sum += map[a][b +1];
        sum += map[a +1][b +1];
        sum += map[a +2][b +1];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b];
        sum += map[a][b +1];
        sum += map[a +1][b];
        sum += map[a +2][b];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b +2];
        sum += map[a +1][b +2];
        sum += map[a +1][b +1];
        sum += map[a +1][b];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a +1][b +2];
        sum += map[a +1][b +1];
        sum += map[a +1][b];
        sum += map[a][b];
        if(max<sum){
            max = sum;
        }
    }

    private static void case4(int a, int b) {
        int sum;
        sum=0;
        sum += map[a][b];
        sum += map[a +1][b];
        sum += map[a +1][b +1];
        sum += map[a +2][b +1];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b +2];
        sum += map[a][b +1];
        sum += map[a +1][b +1];
        sum += map[a +1][b];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a +2][b];
        sum += map[a +1][b];
        sum += map[a +1][b +1];
        sum += map[a][b +1];
        if(max<sum){
            max = sum;
        }
        sum=0;
        sum += map[a][b];
        sum += map[a][b +1];
        sum += map[a +1][b +1];
        sum += map[a +1][b +2];
        if(max<sum){
            max = sum;
        }
    }

    private static void case3(int a, int b) {
        int sum;
        sum=0;
        sum += map[a][b];
        sum += map[a][b +1];
        sum += map[a][b +2];
        sum += map[a +1][b +1];
        if(max<sum){
            max = sum;
        }

        sum=0;
        sum += map[a][b +1];
        sum += map[a +1][b +1];
        sum += map[a +2][b +1];
        sum += map[a +1][b];
        if(max<sum){
            max = sum;
        }

        sum=0;
        sum += map[a +1][b];
        sum += map[a +1][b +1];
        sum += map[a +1][b +2];
        sum += map[a][b +1];
        if(max<sum){
            max = sum;
        }

        sum=0;
        sum += map[a][b];
        sum += map[a +1][b];
        sum += map[a +2][b];
        sum += map[a +1][b +1];
        if(max<sum){
            max = sum;
        }
    }
}