알고리즘

백준 18808번 스티커 붙이기 (JAVA)

박카스마시며코딩 2023. 10. 28. 20:52

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

 

18808번: 스티커 붙이기

혜윤이는 최근에 다양한 대회를 참여하면서 노트북에 붙일 수 있는 스티커들을 많이 받았다. 스티커는 아래와 같이 사각 모눈종이 위에 인쇄되어 있으며, 스티커의 각 칸은 상하좌우로 모두 연

www.acmicpc.net

 

저는 구현을 통해 문제를 해결하였습니다.

각각의 스티커가 위 왼쪽부터해서 들어갈 수 있는지를 판단하고, 들어갈 수 있다면 해당 자리에 바로 스티커를 붙입니다. 모든 지점을 돌았는데도 붙일 수 없다면 시계 방향으로 90도 회전 시키고 위의 로직을 다시 진행하여 제자리로 돌아올 때까지 스티커를 붙일 자리가 없다면 넘어가게 구현하였습니다. 

 

package BOJ.etc;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.function.Function;

public class BOJ_18808 {

    private static final int EMPTY = 0;
    private static final int BLOCK = 1;
    private static final int[] NOT_FOUND = {-1};

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        Function<String, Integer> stoi = Integer::parseInt;
        int n = stoi.apply(st.nextToken());
        int m = stoi.apply(st.nextToken());
        int k = stoi.apply(st.nextToken());
        List<int[][]> stickers = new ArrayList<>();
        for (int s = 0; s < k; s++) {
            st = new StringTokenizer(br.readLine());
            int a = stoi.apply(st.nextToken());
            int b = stoi.apply(st.nextToken());
            int[][] sticker = new int[a][b];
            for (int i = 0; i < a; i++) {
                st = new StringTokenizer(br.readLine());
                for (int j = 0; j < b; j++) {
                    sticker[i][j] = stoi.apply(st.nextToken());
                }
            }
            stickers.add(sticker);
        }
        int result = cal(0, n, m, stickers);
        System.out.println(result);

    }

    private static int cal(int depth, int n, int m, List<int[][]> stickers) {
        int[][] map = new int[n][m];
        for (int[][] sticker : stickers) {
            int[][] nowSticker = sticker;
            for(int i = 0 ; i < 4 ; i++){
                int[] location = findLocation(nowSticker,map,n,m);
                if(location != NOT_FOUND){

                    append(location[0],location[1],map, nowSticker);
                    break;
                }
                nowSticker = rotation(nowSticker);
            }
        }
        return countMap(map,n,m);
    }

    private static int countMap(int[][] map, int n, int m) {
        int cnt = 0;
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < m ; j++){
                if(map[i][j] == BLOCK){
                    cnt++;
                }
            }
        }
        return cnt;
    }

    private static int[] findLocation(int[][] sticker, int[][] map, int n, int m) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (canAppend(i, j, map, sticker, n, m)) {
                    return new int[]{i,j};
                }
            }
        }
        return NOT_FOUND;
    }

    private static void append(int y, int x, int[][] map, int[][] sticker) {
        int stickerMaxY = sticker.length;
        int stickerMaxX = sticker[0].length;
        for (int i = 0; i < stickerMaxY; i++) {
            for (int j = 0; j < stickerMaxX; j++) {
                map[y+i][x+j] += sticker[i][j];
            }
        }
    }

    private static boolean canAppend(int y, int x, int[][] map, int[][] sticker, int n, int m) {
        int stickerMaxY = sticker.length;
        int stickerMaxX = sticker[0].length;
        if (y + stickerMaxY > n || x + stickerMaxX > m) {
            return false;
        }
        for (int i = 0; i < stickerMaxY; i++) {
            for (int j = 0; j < stickerMaxX; j++) {
                if (map[y+i][x+j] + sticker[i][j] > 1) {
                    return false;
                }
            }
        }
        return true;
    }

    private static int[][] rotation(int[][] arr) {
        int n = arr.length;
        int m = arr[0].length;
        int[][] temp = new int[m][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                temp[j][i] = arr[n - i - 1][j];
            }
        }
        return temp;
    }

}