Algorithm/삼성 SW 역량 테스트 기출 문제

[Baekjoon][20061] 모노미노도미노 2

어발 2022. 2. 28. 14:25

출처 - 백준사이트

20061. 모노미노도미노 2

나의 풀이

블록 입력시 초록색맵과 파란색 맵에 알맞은 위치에 블록이 생성하게 한뒤, 동일한 블록이동 함수를 사용하여 구현.
블록이동 함수는 수평도미노 이동함수, 단일 혹은 수직도미노 이동함수 2개로 구현하였다.
주의해야할 반례,
0 0 1 0     0 0 0 0
0 0 1 0     0 0 0 0
1 1 0 1 -> 0 0 1 0 옆의 예시처럼 모든 행이 1인 구간이 먼저 삭제 됨을 유의.
1 0 1 0     1 0 1 0
0 0 1 0     0 0 1 0
0 1 1 1     0 1 1 1
해당 반례 및 답.
8
3 1 0
3 0 1
1 2 1
1 0 0
3 2 1
3 0 1
1 3 1   answer : 1
2 2 1                  14

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

int N, score, remain;
int GreenMap[10][4];
int BlueMap[10][4];

void deleteMap(int (*map)[4], int y) {
    for (int i = y ; i > 4; i--)
        memcpy(map[i], map[i-1], sizeof(map[0]));

    memset(map[4], 0, sizeof(map[0]));
}

void moving_vertical(vector<pair<int,int>> &v, int (*map)[4]) {
    int py1 = -1, px1 = -1, py2 = -1, px2 = -1;
    int ny1 = -1, nx1 = -1, ny2 = -1, nx2 = -1;

    if (v.size() == 2) {
        if (v[0].first > v[1].first) {
            py1 = v[0].first, px1 = v[0].second;
            py2 = v[1].first, px2 = v[1].second;
        }
        else {
            py1 = v[1].first, px1 = v[1].second;
            py2 = v[0].first, px2 = v[0].second;
        }
    }
    else
        py1 = v[0].first, px1 = v[0].second;

    while (1) {
        ny1 = py1 + 1, nx1 = px1;

        if (py2 != -1 && px2 != -1)
            ny2 = py2 + 1, nx2 = px2;

        if (ny1 < 10) {
            if (map[ny1][nx1] == 0) {
                map[py1][px1] = 0;
                map[ny1][nx1] = 1;
                py1 = ny1, px1 = nx1;

                if (py2 != -1 && px2 != -1) {
                    map[py2][px2] = 0;
                    map[ny2][nx2] = 1;
                    py2 = ny2, px2 = nx2;
                }
            }
            else
                break;
        }
        else
            break;
    }

    if (map[py1][0] && map[py1][1] && map[py1][2] && map[py1][3]) {
        score++;
        deleteMap(map, py1);

        if (py2 != -1 && px2 != -1) {
            py2 = py1, px2 = px1;

            if (map[py2][0] && map[py2][1] && map[py2][2] && map[py2][3]) {
                score++;
                deleteMap(map, py2);
            }
        }
    }

    if (map[py2][0] && map[py2][1] && map[py2][2] && map[py2][3]) {
        score++;
        deleteMap(map, py2);
    }

    if (map[5][0] || map[5][1] || map[5][2] || map[5][3]) // 연한분에 속했을때
        deleteMap(map, 9);

    if (map[5][0] || map[5][1] || map[5][2] || map[5][3]) // 연한분에 속했을때
        deleteMap(map, 9);
}

void moving_horizon(vector<pair<int,int>> &v, int (*map)[4]) {
    int py1 = -1, px1 = -1, py2 = -1, px2 = -1;
    int ny1 = -1, nx1 = -1, ny2 = -1, nx2 = -1;

    if (v[0].first > v[1].first) {
        py1 = v[0].first, px1 = v[0].second;
        py2 = v[1].first, px2 = v[1].second;
    }
    else {
        py1 = v[1].first, px1 = v[1].second;
        py2 = v[0].first, px2 = v[0].second;
    }

    while (1) {
        ny1 = py1 + 1, nx1 = px1;
        ny2 = py2 + 1, nx2 = px2;

        if (ny1 < 10 && ny2 < 10) {
            if (map[ny1][nx1] == 0 && map[ny2][nx2] == 0) {
                map[py1][px1] = 0, map[py2][px2] = 0;
                map[ny1][nx1] = 1, map[ny2][nx2] = 1;
                py1 = ny1, px1 = nx1;
                py2 = ny2, px2 = nx2;
            }
            else
                break;
        }
        else
            break;
    }

    if (map[py1][0] && map[py1][1] && map[py1][2] && map[py1][3]) {
        score++;
        deleteMap(map, py1);
    }

    if (map[5][0] || map[5][1] || map[5][2] || map[5][2]) // 연한분에 속했을때
        deleteMap(map, 9);
}

void doBlue(int t, int x, int y) {
    BlueMap[y][3-x] = 1;
    vector<pair<int,int>> block;
    block.push_back({y, 3-x});

    if (t == 1)
        moving_vertical(block, BlueMap);
    else if (t == 2) {
        BlueMap[y+1][3-x] = 1;
        block.push_back({y+1, 3-x});
        moving_vertical(block, BlueMap);
    }
    else if (t == 3) {
        BlueMap[y][3-x-1] = 1;
        block.push_back({y, 3-x-1});
        moving_horizon(block, BlueMap);
    }
}

void doGreen(int t, int x, int y) {
    GreenMap[x][y] = 1;
    vector<pair<int,int>> block;
    block.push_back({x, y});

    if (t == 1)
        moving_vertical(block, GreenMap);
    else if (t == 2) {
        GreenMap[x][y+1] = 1;
        block.push_back({x, y+1});
        moving_horizon(block, GreenMap);
    }
    else if (t == 3) {
        GreenMap[x+1][y] = 1;
        block.push_back({x+1, y});
        moving_vertical(block, GreenMap);
    }
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    cin >> N;

    for (int i = 0 ; i < N ; i++) {
        int t, x, y;

        cin >> t >> x >> y;
        doGreen(t,x,y);
        doBlue(t,x,y);
    }

    cout << score << endl;

    for (int y = 6 ; y < 10 ; y++) {
        for (int x = 0 ; x < 4 ; x++) {
            if (GreenMap[y][x] == 1)
                remain++;

            if (BlueMap[y][x] == 1)
                remain++;
        }
    }

    cout << remain << endl;

    return 0;
}
728x90