[백준] 20061번 모노미노도미노2

donghyeok·2022년 2월 1일
0

알고리즘 문제풀이

목록 보기
23/144

문제 설명

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

문제 풀이

  • 시뮬레이션 문제이다.
  • 초록판에 블록을 떨어뜨리는 로직과, 파란판에 블록을 떨어뜨리는 로직에서 공통부분을 찾아 일반화를 시키는 것에 유의해서 구현하였다.
  • 아래는 가장 구현에 신경을 썼던 블록을 떨어뜨리는 로직이다.
  • dropBlock(케이스, 열좌표, 색상)

    • 케이스 = 1 : 열좌표에 1칸 짜리 블록 놓기
    • 케이스 = 2 : 열좌표에 가로 2칸짜리 블록 놓기
    • 케이스 = 3 : 열좌표에 세로 2칸짜리 블록 놓기
  • (t = 1, x, y) -> dropBlock(case1, y, 초록) / dropBlock(case1, x, 파랑)
    (t = 2, x, y) -> dropBlock(case2, y, 초록) / dropBlock(case3, x, 파랑)
    (t = 3, x, y) -> dropBlock(case3, y, 초록) / dropBlock(case2, x, 파랑)

소스 코드 (JAVA)

import java.util.Scanner;

public class Main {
    public static int[][][] map = new int[2][6][4]; // [보드번호][x][y]

    public static void outerDown() {
        int downSize;
        for (int k = 0; k < 2; k++) {
            downSize = 0;
            for (int i = 0; i < 2; i++) {
                boolean flag = false;
                for (int j = 0; j < 4; j++) {
                    if (map[k][i][j] == 1)
                        flag = true;
                }
                if (flag) downSize++;
            }
            //downSize만큼 내려줌
            for (int s = 0; s < downSize; s++) {
                for (int y = 0; y < 4; y++) {
                    for (int x = 5; x >= 0; x--)
                        if (x == 0)
                            map[k][x][y] = 0;
                        else
                            map[k][x][y] = map[k][x-1][y];
                }
            }
        }
    }

    public static boolean calScore(int bType) {
        for (int i = 0; i < 6; i++) {
            boolean flag = true;
            for (int j = 0; j < 4; j++) {
                if (map[bType][i][j] == 0)
                    flag = false;
            }
            //한 줄 완성되었으면 해당 row 위부터 쭉 내려줌
            if (flag) {
                for (int y = 0; y < 4; y++) {
                    for (int x = i; x >= 0; x--) {
                        if (x == 0)
                            map[bType][x][y] = 0;
                        else
                            map[bType][x][y] = map[bType][x - 1][y];
                    }
                }
                return true;
            }
        }
        return false;
    }

    //bType 0: 초록, 1: 파랑
    public static void dropBlock(int type, int ind, int bType) {
        int targetRow = 5;
        for (int i = 0; i < 6; i++) {
            // 1x1 블록 or 1x2 세로블록
            if (type == 1 || type == 3) {
                // 블록을 만나면 멈추고 이전 row를 선택
                if (map[bType][i][ind] == 1) {
                    targetRow = i - 1;
                    break;
                }
            }
            // 1x2 가로블록
            else {
                // ind, ind+1에서 블록을 만나면 멈추고 이전 row를 선택
                if (map[bType][i][ind] == 1 || map[bType][i][ind+1] == 1) {
                    targetRow = i - 1;
                    break;
                }
            }
        }
        map[bType][targetRow][ind] = 1;
        if (type == 2) map[bType][targetRow][ind+1] = 1;
        else if (type == 3) map[bType][targetRow-1][ind] = 1;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N, totalScore, totalBlockCnt;
        totalScore = 0;
        totalBlockCnt = 0;
        N = sc.nextInt();
        //N 개의 입력을 받아
        for (int n = 0; n < N; n++) {
            int t, x, y;
            t = sc.nextInt(); x = sc.nextInt(); y = sc.nextInt();
            //1. 블록 떨어뜨림
            dropBlock(t, y, 0);
            if (t == 1) dropBlock(1, x, 1);
            else if (t == 2) dropBlock(3, x, 1);
            else if (t == 3) dropBlock(2, x, 1);
            //2. 점수 계산해줌
            while (calScore(0)) { totalScore++; }
            while (calScore(1)) { totalScore++; }
            //3. 연한 부분 내려줌
            outerDown();
        }
        //결과 계산
        for (int k = 0; k < 2; k++) {
            for (int i = 2; i < 6; i++) {
                for (int j = 0; j < 4; j++) {
                    if (map[k][i][j] == 1)
                        totalBlockCnt++;
                }
            }
        }
        System.out.println(totalScore);
        System.out.println(totalBlockCnt);
    }
}

0개의 댓글