본문 바로가기

Algorithm/BOJ

[BOJ-19235][시뮬레이션] 모노미노도미노 - Java

문제 바로가기

 

19235번: 모노미노도미노

모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,

www.acmicpc.net

 

휴 두시간도 더걸렸네;;;

아 진짜 스트레습니다...

하지만 풀었다

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

public class Main {
    static class Dir{
        int y, x;
        Dir(int y, int x){
            this.y = y; this.x = x;
        }
    }

    static interface Block{}

    static class OneBlock implements Block{
        Dir loc;
        OneBlock(int y, int x){
            this.loc = new Dir(y, x);
        }
    }

    static class HorBlock implements Block{
        Dir loc1, loc2;
        HorBlock(int y, int x){
            this.loc1 = new Dir(y, x); this.loc2 = new Dir(y, x + 1);
        }
    }

    static class VerBlock implements Block{
        Dir loc1, loc2;
        VerBlock(int y, int x){
            this.loc1 = new Dir(y, x); this.loc2 = new Dir(y + 1, x);
        }
    }

    static int[][] gBoard = new int[10][4];
    static int[][] bBoard = new int[10][4];
    static int score, max;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        for(int i = 1; i <= N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            int t = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            int x = Integer.parseInt(st.nextToken());
            max = i;
            switch(t) {
            case 1: moveDown(gBoard, new OneBlock(y, x), i); moveDown(bBoard, new OneBlock(x, y), i); break;
            case 2: moveDown(gBoard, new HorBlock(y, x), i); moveDown(bBoard, new VerBlock(x, y), i); break;
            case 3: moveDown(gBoard, new VerBlock(y, x), i); moveDown(bBoard, new HorBlock(x, y), i); break;
            }

            checkScore(gBoard);
            checkScore(bBoard);

            checkSpecialArea(gBoard);
            checkSpecialArea(bBoard);

            while(true) {
                if(checkScore(gBoard) == false) break;
            }
            while(true) {
                if(checkScore(bBoard) == false) break;
            }
        }

        System.out.println(score);
        System.out.println(checkTile(gBoard) + checkTile(bBoard));
    }

    public static void moveDown(int[][] board, Block block, int no) {
        if(block instanceof OneBlock) {
            int y = 0, x = ((OneBlock) block).loc.x;
            for(y = ((OneBlock) block).loc.y; y <10; y++) {
                if(board[y][x] == 0) continue;
                break;
            }
            board[y - 1][x] = no;
        }else if(block instanceof HorBlock) {
            int y = 0, x1 = ((HorBlock) block).loc1.x, x2 = ((HorBlock) block).loc2.x;
            for(y = ((HorBlock) block).loc1.y; y <10; y++) {
                if(board[y][x1] == 0 && board[y][x2] == 0) continue;
                break;
            }
            board[y - 1][x1] = no; board[y - 1][x2] = no;
        }else if(block instanceof VerBlock){
            int y = 0, x = ((VerBlock) block).loc1.x;
            for(y = ((VerBlock) block).loc2.y; y <10; y++) {
                if(board[y][x] == 0) continue;
                break;
            }
            board[y - 2][x] = no; board[y - 1][x] = no;
        }
    }

    public static boolean checkScore(int[][] board) {
        List<Integer> removeIdx = new ArrayList<>();
        for(int i = 6; i < 10; i++) {
            boolean flag = true;
            for(int j = 0; j < 4; j++) {
                flag = flag & board[i][j] != 0;
            }
            if(flag) removeIdx.add(i);
        }
        score += removeIdx.size();

        if(removeIdx.size() >= 1) {
            for(int i = removeIdx.get(removeIdx.size() - 1); i >= removeIdx.size(); i--) {
                System.arraycopy(board[i - removeIdx.size()], 0, board[i], 0, 4);
            }
            for (int i = 4; i < 4 + removeIdx.size(); i++) {
                for (int j = 0; j < 4; j++) { 
                    board[i][j] = 0;
                }
            }

            boolean[] v = new boolean[max + 1];

            for(int i = 9; i >= 4; i--) {
                for(int j = 0; j < 4; j++) {
                    int curNo = board[i][j];
                    if(board[i][j] == 0 || v[board[i][j]]) continue;
                    v[board[i][j]] = true;
                    if(board[i][j] == board[i - 1][j]) {

                        for(int k = i + 1; k < 10; k++) {
                            if(k == 9 && board[k][j] == 0) {
                                board[i][j] = 0; board[i - 1][j] = 0; 
                                board[k][j] = curNo; board[k - 1][j] = curNo; break;
                            }
                            if(board[k][j] == 0) continue;
                            board[i][j] = 0; board[i - 1][j] = 0; 
                            board[k - 1][j] = curNo; board[k - 2][j] = curNo; break;
                        }

                    }else if(j + 1 <= 3 && board[i][j] == board[i][j + 1]) {
                        for(int k = i + 1; k < 10; k++) {
                            if(k ==9 && board[k][j] == 0 && board[k][j + 1] == 0) {
                                board[i][j] = 0; board[i][j + 1] = 0; 
                                board[k][j] = curNo; board[k][j + 1] = curNo; break;
                            }
                            if(board[k][j] == 0 && board[k][j + 1] == 0) continue;
                            board[i][j] = 0; board[i][j + 1] = 0; 
                            board[k - 1][j] = curNo; board[k - 1][j + 1] = curNo; break;
                        }

                    }else {
                        for(int k = i + 1; k < 10; k++) {
                            if(k == 9 && board[k][j] == 0) {
                                board[i][j] = 0; board[k][j] = curNo; break;
                            }
                            if(board[k][j] == 0 ) continue;
                            board[i][j] = 0; board[k - 1][j] = curNo; break;
                        }
                    }

                }
            }
        }

        return removeIdx.size() > 0 ? true : false;
    }

    public static void checkSpecialArea(int[][] board) {
        int cnt = 0;
        for(int i = 4; i < 6; i++) {
            boolean flag = false;
            for(int j = 0; j < 4; j++) {
                flag = flag | board[i][j] != 0;
            }
            cnt = flag == true ? cnt + 1: cnt;
        }

        for(int c = 0; c < cnt; c++) {
            for(int i = 9; i >= 4; i--) {
                System.arraycopy(board[i - 1], 0, board[i], 0, 4);
            }
        }
    }

    public static int checkTile(int[][] board) {
        int tileCnt = 0;
        for(int i = 6; i < 10; i++) {
            for(int j = 0; j < 4; j++) {
                if(board[i][j] != 0) tileCnt++;
            }
        }
        return tileCnt;
    }

}

코드 정말 더럽다...

하지만 풀었지

 

맨 처음에 40분동안 문제에 나와있는 대로 내리고 오른쪽으로 밀고 난리부르스를 쳤습니다.

하지만 이내 깨달았습니다 살포시 반 접은 걸로 생각하고 똑같은 모양에서 로직을 처리하도록 하는게 훨배 편하다는 것을..

다행히 파라미터로 board[][] 만 넘겨주도록 바꾸면 되니깐 고건 오래 안걸렸습니다.

 

문제는 내리는거...

이건 뭐... 말로 설명을 할 수가 없습니다... 하라는 대로 하면 되는데... 그걸 못해서....

젤 안됐던 부분은 저는 한줄 없애고 나서 다시 내릴 때였습니다. 반복문에서 다음 부분이 0이면 continue를 하고 0이 아니면 고 앞까지 내리는 코드를 짰는데 이러면 맨 마지막까지 내리는 걸 체크를 못합니다.... 아주 더럽고 지저분하게 따로 걍 빼서 체크했습니다.....

 

아 그리고 점수 체크하고 내리는 부분은 없앨 줄이 없을 때까지 해야 하니깐 checkScore() 메소드에서 반환값으로 없앨 줄이 있는지 없는지를 반환해서 체크했습니당..

 

 

 

코테 자신이 없다!!!

하지만 화이팅 ^^;;