열공스토리

[백준] 18808 - 스티커 붙이기 (JAVA 객체지향적으로 설계해 보기) 본문

백준

[백준] 18808 - 스티커 붙이기 (JAVA 객체지향적으로 설계해 보기)

열쩡열쩡열쩡_ 2023. 11. 20. 15:13
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Main {
    static int N;
    static int M;

    static class Input {
        private final Scanner scanner;

        public Input() {
            this.scanner = new Scanner(System.in);
        }

        public int inputLaptopRow() {
            return scanner.nextInt();
        }

        public int inputLaptopCol() {
            return scanner.nextInt();
        }

        public int inputStickerCount() {
            return scanner.nextInt();
        }

        public List<int[]> inputSticker() {
            int R = scanner.nextInt();
            int C = scanner.nextInt();
            List<int[]> list = new ArrayList<>();
            for (int i = 0; i < R; i++) {
                for (int j = 0; j < C; j++) {
                    if (scanner.nextInt() == 1) {
                        list.add(new int[]{i, j});
                    }
                }
            }
            return list;
        }
    }

    static class Sticker {
        private List<int[]> coordinate; // int[0] : x, int[1] : y
        private int maxRow;

        public Sticker(List<int[]> coordinate) {
            this.coordinate = coordinate;
            this.maxRow = setMaxRow();
        }

        public void rotateQuarterClockwise() {
            List<int[]> coordinateAfterRotate = new ArrayList<>();
            for (int[] i : coordinate) {
                coordinateAfterRotate.add(new int[]{i[1], maxRow - i[0]});
            }
            this.coordinate = coordinateAfterRotate;
            this.maxRow = setMaxRow();
        }

        public boolean isPossibleAttach(int r, int c, Laptop laptop) {
            return coordinate.stream()
                    .allMatch(e -> sizeConstraint(r + e[0], c + e[1])
                            && laptop.isExistSpace(r + e[0], c + e[1])
                    );
        }

        private boolean sizeConstraint(int r, int c) {
            return r < N && c < M;
        }

        private int setMaxRow() {
            return coordinate.stream()
                    .map(e -> e[0])
                    .max(Integer::compareTo)
                    .get();
        }
    }

    static class Laptop {
        private int map[][];

        public Laptop(int[][] map) {
            this.map = map;
        }

        public boolean isAttachSticker(Sticker sticker) {
            for (int i = 0; i < map.length; i++) {
                for (int j = 0; j < map[i].length; j++) {
                    if (sticker.isPossibleAttach(i, j, this)) {
                        int finalI = i;
                        int finalJ = j;
                        sticker.coordinate.stream()
                                .forEach(e -> attach(e[0] + finalI, e[1] + finalJ));
                        return true;
                    }
                }
            }
            return false;
        }

        private void attach(int r, int c) {
            map[r][c] = 1;
        }

        public boolean isExistSpace(int r, int c) {
            if (map[r][c] == 0) {
                return true;
            }
            return false;
        }

        public int getTotalSquare() {
            return (int) Arrays.stream(map)
                    .flatMapToInt(Arrays::stream)
                    .filter(e -> e == 1)
                    .count();
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            for (int i[] : map) {
                sb.append(Arrays.toString(i) + "\\n");
            }
            return sb.toString();
        }
    }

    public static void main(String[] args) {
        Input input = new Input();
        N = input.inputLaptopRow();
        M = input.inputLaptopCol();
        int K = input.inputStickerCount();

        Laptop laptop = new Laptop(new int[N][M]);
        while (K-- > 0) {
            Sticker sticker = new Sticker(input.inputSticker());
            int rotationCount = 4;
            while (rotationCount-- > 0) {
                if (laptop.isAttachSticker(sticker)) {
                    break;
                }
                sticker.rotateQuarterClockwise();
            }
        }

        System.out.println(laptop.getTotalSquare());
    }
}