본문 바로가기
  • 개발을 사랑하는 실실쟌의 블로그입니다
PS문제들

[백준] 20061: 모노미노도미노 2 (C++)

by 실실쟌 2022. 9. 28.

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

 

20061번: 모노미노도미노 2

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

www.acmicpc.net

 

소요 시간

골드 2 기준 1시간 정도 소요되었습니다. 골드 2 문제치고 크게 까다롭지 않은 문제였습니다.

구상

문제는 블록 놓기 - 점수 계산 - 0,1 줄 처리 의 과정을 따라야 합니다.

1. 블록 놓기

 저의 경우 blue와 green을 서로 다른 배열에 상태관리하여, 각자 4x6 크기를 가지게 하였고 두 배열 모두 왼쪽 상단이 0,0이 되게끔 했습니다. 이렇게 하면 블록을 놓을 때, blue의 type 2 블록을 처리하는 방법이 green의 type 3 블록을 처리하는 방법이 되고, 반대도 마찬가지입니다. 또한, (3,0) 자리에 1칸짜리 블록이 놓인다면 green은 y좌표가 0이면서 가능한 가장 큰 x좌표를 갖는 자리에 블록이 배치될 것이고, blue는 y좌표가 3이면서 가능한 가장 큰 x좌표를 갖는 자리에 블록이 배치될 것입니다. 즉 y좌표로 green은 y좌표를 가져가고 blue는 x좌표를 가져가면서, 최대한 큰 x를 갖는 비어있는 좌표를 구하면 블록이 놓일 자리가 됩니다.

2. 점수 계산

 전체 줄이 다 채워지면 배열에서 해당 줄을 지우고, 맨 앞에 0으로 가득찬 배열을 삽입하는 식으로 구현했습니다.

3. 0, 1 줄 처리

 마찬가지로 0과 1 줄을 보고 1이 있는 줄의 개수만큼 배열의 마지막 줄을 지우고, 맨 앞에 0으로 가득찬 배열을 삽입하는 식으로 구현했습니다.

 

코드

#include <string>
#include <vector>
#include<iostream>
#include <climits>
#include<queue>
#include<cmath>
#include<algorithm>

using namespace std;
vector<vector<int> > green;
vector<vector<int> > blue;

void special_area() {
    vector<int> add; add.resize(4);

    int greencnt = 0; int bluecnt = 0;
    for(int i = 0; i < 2; i++) {
        for(int j=0; j<4; j++) {
            if(green[i][j] == 1) {
                greencnt += 1;
                break;
            }
        }
        for(int j=0; j<4; j++) {
            if(blue[i][j] == 1) {
                bluecnt += 1;
                break;
            }
        }
    }
    while(greencnt > 0) {
        greencnt --;
        green.erase(green.end()-1);
        green.insert(green.begin(), add);
    }
    while(bluecnt > 0) {
        bluecnt --;
        blue.erase(blue.end()-1);
        blue.insert(blue.begin(), add);
    }
}

int get_score() {
    int score = 0;
    bool greenFull[6]; bool blueFull[6];
    fill_n(greenFull, 6, true);
    fill_n(blueFull, 6, true);
    for(int i=0; i<6; i++) {
        //green
        for(int j=0; j<4; j++) {
            if(green[i][j] == 0) {
                greenFull[i] = false; break;
            }
        }
        //blue
        for(int j=0; j<4; j++) {
            if(blue[i][j] == 0) {
                blueFull[i] = false; break;
            }
        }
    }

    //행 삭제
    vector<int> add; add.resize(4);
    for(int i=0; i<6; i++) {
        if(greenFull[i]) {
            green.erase(green.begin() + i);
            green.insert(green.begin(), add);
            score ++;
        }
        if(blueFull[i]) {
            blue.erase(blue.begin() + i);
            blue.insert(blue.begin(), add);
            score ++;
        }
    }
    return score;
}

void do_command(int t, int x, int y) {
    //green
    int nx = 0; int ny = y;
    if(t == 1) {
        while(nx < 6 && green[nx][ny] == 0) {
            nx ++;
        }
        green[nx-1][ny] = 1;
    }
    else if(t == 2) {
        while(nx < 6 && green[nx][ny] == 0 && green[nx][ny+1] == 0) {
            nx ++;
        }
        green[nx-1][ny] = 1; green[nx-1][ny+1] = 1;
    }
    else if(t == 3) {
        while(nx+1 < 6 && green[nx][ny] == 0 && green[nx+1][ny] == 0) {
            nx ++;
        }
        green[nx-1][ny] = 1; green[nx][ny] = 1;
    }
    //blue
    nx = 0; ny = x;
    if(t == 1) {
        while(nx < 6 && blue[nx][ny] == 0) {
            nx ++;
        }
        blue[nx-1][ny] = 1;
    }
    else if(t == 3) {
        while(nx < 6 && blue[nx][ny] == 0 && blue[nx][ny+1] == 0) {
            nx ++;
        }
        blue[nx-1][ny] = 1; blue[nx-1][ny+1] = 1;
    }
    else if(t == 2) {
        while(nx+1 < 6 && blue[nx][ny] == 0 && blue[nx+1][ny] == 0) {
            nx ++;
        }
        blue[nx-1][ny] = 1; blue[nx][ny] = 1;
    }
}

int main(int argc, char** argv)
{
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int n;
    cin >> n;
    green.resize(6); blue.resize(6);
    for(int i=0; i<6; i++) {
        green[i].resize(4);
        blue[i].resize(4);
    }

    int score = 0;

    for(int i=0; i<n; i++) {
        int t, x, y;
        cin >> t >> x >> y;
        do_command(t, x, y);
        score += get_score();
        special_area();
    }

    int cnt = 0;

    for(int i=0; i<6; i++) {
        for(int j=0; j<4; j++) {
            if(green[i][j] == 1) cnt ++;
            if(blue[i][j] == 1) cnt ++;
        }
    }
    
    cout << score << "\n" << cnt << "\n";

    return 0;
}

 

댓글