[java]모노미노도미노 2 - 백준20061

문제



풀이

문제 해석을 하자면,

  • 굉장히 조건 설명을 잘해주고 있으나 굉장히 구현이 긴 문제…
  • 블록을 놓은 위치가 순서대로 주어졌을 때, 얻은 점수와 초록색 보드와 파란색 보드에 타일이 있는 칸의 개수를 모두 구해보자.


풀이

  • 이 문제의 경우 그림으로 잘 설명을 해주기 때문에 무엇을 구현해야 하는지는 알기 쉽다.
  • 다만, 구현할게 많아서 이를 구현하는데 오래걸렸다ㅜㅜ
  • 하나씩 알아보자.
    • 입력좌표 형태 : (x,y) -> 행,열 -> (0,0) 부터
    • 타일종류 : 3가지 -> 타일 최대크기 2
      • 배열의 요소에 1로 표시해서 구분하자
    • “0~1 인덱스 특별 배열자리” 는 턴 종료마다 항상 비어있게된다. (“삭제, 이동 등등 때문”)
      • 따라서 따로 Red 배열 없이 “0~1 인덱스” 자리에 타일 삽입할 것이다.
      • 타일종류 3가지 전부 최대크기 2라서 충분히 가능
    • 크게 3가지 규칙을 준수해야 한다.
      • 삽입할때 규칙 -> insert
      • 삭제할때 규칙 -> delete
      • 0~1 인덱스쪽 제거할때 규칙 -> zeroOne
    • 이때, 이동함수 2개만 구현해서 재사용하자.
      • 행이나 열전체 1칸씩 이동 함수 -> moveCol, moveRow
      • 타일 종류별(3종류) 배열 끝까지 이동 함수 -> moveBlueTile, moveGreenTile



코드

public static int N;
public static int result;
public static int[][] G = new int[6][6];
public static int[][] B = new int[6][6];

// 타일 이동함수(BLUE)
public static void moveBlueTile(int t, int x, int y) {
    if(t==1) {
        // (x, y)
        int cy = y;
        while(true) {
            y+=1;
            if(y>=6) break;
            if(B[x][y]==1) break;
        }
        y-=1;
        B[x][cy] = 0;
        B[x][y] = 1;

    }else if(t==2) {
        // (x, y), (x, y+1)
        int cy = y+1;
        while(true) {
            y+=1;
            if(y>=6) break;
            if(B[x][y]==1) break;
        }
        y-=1;
        B[x][cy] = 0; B[x][cy-1] = 0;
        B[x][y] = 1; B[x][y-1] = 1;

    }else {
        // (x, y), (x+1, y)
        int cy = y;
        while(true) {
            y+=1;
            if(y>=6) break;
            if(B[x][y]==1 || B[x+1][y]==1) break;
        }
        y-=1;
        B[x][cy] = 0; B[x+1][cy] = 0;
        B[x][y] = 1; B[x+1][y] = 1;
    }

}
// 타일 이동함수(GREEN)
public static void moveGreenTile(int t, int x, int y) {
    if(t==1) {
        // (x, y)
        int cx = x;
        while(true) {
            x+=1;
            if(x>=6) break;
            if(G[x][y]==1) break;
        }
        x-=1;
        G[cx][y] = 0;
        G[x][y] = 1;
    }else if(t==2) {
        // (x, y), (x, y+1)
        int cx = x;
        while(true) {
            x+=1;
            if(x>=6) break;
            if(G[x][y]==1 || G[x][y+1]==1) break;
        }
        x-=1;
        G[cx][y] = 0; G[cx][y+1] = 0;
        G[x][y] = 1; G[x][y+1] = 1;

    }else {
        // (x, y), (x+1, y)
        int cx = x+1;
        while(true) {
            x+=1;
            if(x>=6) break;
            if(G[x][y]==1) break;
        }
        x-=1;
        G[cx][y] = 0; G[cx-1][y] = 0;
        G[x][y] = 1; G[x-1][y] = 1;
    }
}

// 열단위 1칸 이동함수
public static void moveCol(int ny) {
    if(ny+1>=6) return;
    for(int i=0;i<4;i++) {
        B[i][ny+1] = B[i][ny];
        B[i][ny] = 0; // 이동했으니 이전값은 제거
    }
}
// 행단위 1칸 이동함수
public static void moveRow(int nx) {
    if(nx+1>=6) return;
    for(int i=0;i<4;i++) {
        G[nx+1][i] = G[nx][i];
        G[nx][i] = 0; // 이동했으니 이전값은 제거
    }
}

public static void insert(int t, int x, int y) {
    int bx = x; int by = y;
    int rx = x; int ry = y;
    //[0~1 특별배열] 자리로 이동위해 y수정 -> BLUE
    if(by==1) by-=1;
    else if(by==2) by-=2;
    else if(by==3) by-=3;
    //[0~1 특별배열] 자리로 이동위해 x수정 -> RED
    if(rx==1) rx-=1;
    else if(rx==2) rx-=2;
    else if(rx==3) rx-=3;

    moveBlueTile(t, x, by);
    moveGreenTile(t, rx, y);
}

public static void delete() {
    // BLUE 삭제 있으면?
    int[] blues = new int[6]; // 삭제 인덱스(열) 담는 배열
    int idx = 0;
    for(int i=0; i<6; i++) {
        boolean check = true;
        for(int j=0; j<4; j++) {
            if(B[j][i]==0) check=false;
        }
        if(check) blues[idx++]=i;
    }
    result += idx;
    for(int k=0; k<6; k++) {
        if(blues[k]==0) break;
        for(int i=blues[k]; i>0; i--) { // 삭제 인덱스부터 1칸씩 밀어주기
            moveCol(i-1);
        }
    }

    // GREEN 삭제 있으면?
    int[] greens = new int[6]; // 삭제 인덱스(행) 담는 배열
    idx = 0;
    for(int i=0; i<6; i++) {
        boolean check = true;
        for(int j=0; j<4; j++) {
            if(G[i][j]==0) check=false;
        }
        if(check) greens[idx++]=i;
    }
    result += idx;
    for(int k=0; k<6; k++) {
        if(greens[k]==0) break;
        for(int i=greens[k]; i>0; i--) { // 삭제 인덱스부터 1칸씩 밀어주기
            moveRow(i-1);
        }
    }
}

public static void zeroOne() {
    //BLUE
    int count = 0;
    for(int j=0; j<2; j++){
        for(int i=0; i<4; i++){
            if(B[i][j]==1) {
                count++; break;
            }
        }
    }
    for(int i=0; i<count; i++){
        for(int j=5; j>0; j--) { // 끝자리 삭제! 인덱스 1칸씩 밀어주기
            moveCol(j-1);
        }
    }

    //Green
    count = 0;
    for(int i=0; i<2; i++){
        for(int j=0; j<4; j++){
            if(G[i][j]==1) {
                count++; break;
            }
        }
    }
    for(int i=0; i<count; i++){
        for(int j=5; j>0; j--) { // 끝자리 삭제! 인덱스 1칸씩 밀어주기
            moveRow(j-1);
        }
    }
}

public static void main(String[] args) throws Exception {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    N = Integer.parseInt(br.readLine());
    for(int i=0; i<N; i++) {
        //input
        StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
        int t = Integer.parseInt(stk.nextToken());
        int x = Integer.parseInt(stk.nextToken());
        int y = Integer.parseInt(stk.nextToken());
        //run
        insert(t,x,y);
        //      debugPrint(i, "insert"); //debug

        delete();
        //      debugPrint(i, "delete"); //debug

        zeroOne();
        //      debugPrint(i, "zeroOne"); //debug
    }
    //output
    System.out.println(result);
    int result2 = 0;
    for(int i=0; i<6;i++){
        for(int j=0; j<6; j++){
            if(B[i][j]!=0)result2++;
            if(G[i][j]!=0)result2++;
        }
    }
    System.out.println(result2);
}

public static void debugPrint(int i, String name){
    //debug
    for(int j=0; j<4;j++)
        System.out.println(Arrays.toString(B[j]));
    System.out.println(i+"번 "+name+" Blue");
    for(int j=0; j<6;j++)
        System.out.println(Arrays.toString(G[j]));
    System.out.println(i+"번 "+name+" Green");
}



느낀점

debug로 출력문을 찍어보면서 함수 하나하나 구현할 때 잘 동작하는지 찍어보길 추천

댓글남기기