반응형

문제출처

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

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다. 정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다. 아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누

www.acmicpc.net

 

문제풀이

N x M 배열에 테트리스 도형들을 적절히 회전하여 1개를 놓았을때 놓인 칸들의 최대 합을 구하는 문제입니다.

삼성 기출문제답게 map위에서 동,북,서,남 방향으로 탐색해서 풀이하면 될것이라 생각했지만 'ㅜ'모양은 기존 dfs와 다른 방식으로 탐색해야했습니다.

'ㅜ' 모양을 탐색하는 제 아이디어는 다음과 같습니다.

 

1. 해당 위치를 기준으로 동,북,서,남 방향 모두 탐색하며 map에 저장된 값들을 더한다.

2. 탐색 시 매번 map의 최소값을 구한다.

3. 모두 탐색한 뒤 최소값을 빼준다.

즉, 현재위치 + 4방향 - 4방향중 최소값으로 'ㅜ'모양을 탐색했습니다.

+ 모양으로 탐색한 뒤 가장 최소값을 빼주면 'ㅜ'의 회전체 모양이 나오기 때문입니다.

 

소스코드

https://github.com/sw93/algorithm/blob/master/SW_TEST(samsung)/BOJ_14500/boj14500.java

 

sw93/algorithm

problem solve. Contribute to sw93/algorithm development by creating an account on GitHub.

github.com

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    private static int n, m, ans=0;
    private static int dy[] = {0, -1, 0, 1};
    private static int dx[] = {1, 0, -1, 0};
    private static int map[][];
    private static boolean visit[][];

    public static void main(String[] args) throws Exception {
        init();
        for (int y=0; y<n; y++) {
            for (int x=0; x<m; x++) {
                dfs(y, x, 0, 0);
                checkException(y, x);
            }
        }
        System.out.println(ans);
    }

    private static void dfs(int y, int x, int sum, int count) {
        if (count == 4) {
            ans = Math.max(ans, sum);
            return;
        }

        for (int i=0; i<4; i++) {
            int ny = y+dy[i];
            int nx = x+dx[i];
            if (ny<0 || nx<0 || ny>=n || nx>=m || visit[ny][nx]) continue;
            visit[ny][nx] = true;
            dfs(ny, nx, sum+map[ny][nx], count+1);
            visit[ny][nx] = false;
        }
    }

    private static void checkException(int y, int x) {
        int sum = map[y][x];
        int count = 1;
        int min = 987654321;

        for (int i=0; i<4; i++) {
            int ny = y+dy[i];
            int nx = x+dx[i];
            if (ny<0 || nx<0 || ny>=n || nx>=m) continue;
            sum += map[ny][nx];
            min = Math.min(min, map[ny][nx]);
            count++;
        }

        if (count == 5) {
            sum -= min;
        }
        ans = Math.max(ans, sum);
    }

    private static void init() throws Exception {
        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];
        visit = new boolean[n][m];

        for (int y = 0; y < n; y++) {
            st = new StringTokenizer(br.readLine());
            for (int x = 0; x < m; x++) {
                map[y][x] = Integer.parseInt(st.nextToken());
            }
        }
    }
}
반응형

'Algorithm' 카테고리의 다른 글

[BOJ 16234] 인구 이동  (0) 2020.04.27
[BOJ 17144] 미세먼지 안녕!  (0) 2020.04.24
[BOJ 10819] 차이를 최대로  (0) 2020.04.21
[BOJ 16236] 아기상어  (0) 2020.04.21
[BOJ 15683] 감시  (0) 2020.04.20

+ Recent posts