[백준] 21611번

Jeanine·2022년 4월 28일
0

baekjoon

목록 보기
98/120
post-thumbnail
post-custom-banner

💻 C++ 기반

마법사 상어와 블리자드
https://www.acmicpc.net/problem/21611

✔️ 2차원 배열을 1차원 배열로 바꿔서 동작 -> 다시 2차원 배열로 복귀
✔️ 1차원 배열에서 처리할 때는 투포인터 사용


#include <cstdio>
#include <algorithm>

#define MAX_N 50

using namespace std;

int N, M;
int board[MAX_N][MAX_N];
int temp[MAX_N * MAX_N] = {0,};
int sharkY, sharkX;
int dy[5] = {0, -1, 1, 0, 0}; // X, 북, 남, 서, 동
int dx[5] = {0, 0, 0, -1, 1};
int dirY[4] = {0, 1, 0, -1}; // 서, 남, 동, 북
int dirX[4] = {-1, 0, 1, 0};
int beads[4];

void removeBeads(int d, int s)
{
    int curY = sharkY;
    int curX = sharkX;
    while (s--)
    {
        int nextY = curY + dy[d];
        int nextX = curX + dx[d];
        board[nextY][nextX] = 0;
        curY = nextY;
        curX = nextX;
    }
}

void flatten()
{
    int limit1 = N * 2 - 1;
    int dir = 0;
    int curY = sharkY;
    int curX = sharkX;

    int idx = 1;
    for (int i = 0; i < limit1; i++)
    {
        int limit2 = i == limit1 - 1 ? i / 2 : i / 2 + 1;
        for (int j = 0; j < limit2; j++)
        {
            int nextY = curY + dirY[dir];
            int nextX = curX + dirX[dir];
            temp[idx] = board[nextY][nextX];
            curY = nextY;
            curX = nextX;
            idx++;
        }
        dir = (dir + 1) % 4;
    }
}

void moveBeads()
{
    int left = 1;
    int right = 1;
    while (left < N * N)
    {
        if (temp[left] == 0)
        {
            right = left + 1;
            while (right < N * N)
            {
                if (temp[right] != 0)
                {
                    swap(temp[left], temp[right]);
                    break;
                }
                right++;
            }
        }
        left++;
    }
}

bool explodeBeads()
{
    bool isThereExplosion = false;
    int left = 1;
    int right = 2;
    while (right < N * N)
    {
        if (temp[left] == temp[right])
        {
            right++;
        }
        else
        {
            if (right - left >= 4)
            {
                isThereExplosion = true;
                beads[temp[left]] += (right - left);
                for (int i = left; i < right; i++)
                {
                    temp[i] = 0;
                }
            }
            left = right;
            right = left + 1;
        }
    }
    return isThereExplosion;
}

void changeBeads()
{
    int temp_copy[MAX_N * MAX_N] = {0,};
    int idx = 1;
    int left = 1;
    int right = 2;
    while (right < N * N)
    {
        if (temp[left] == temp[right])
        {
            right++;
        }
        else
        {
            temp_copy[idx] = right - left;
            idx++;
            if (idx >= N * N)
            {
                break;
            }
            temp_copy[idx] = temp[left];
            idx++;
            if (idx >= N * N)
            {
                break;
            }
            left = right;
            right = left + 1;
        }
    }
    for (int i = 0; i < N * N; i++)
    {
        temp[i] = temp_copy[i];
    }
}

void backToBoard()
{
    int limit1 = N * 2 - 1;
    int dir = 0;
    int curY = sharkY;
    int curX = sharkX;

    int idx = 1;
    for (int i = 0; i < limit1; i++)
    {
        int limit2 = i == limit1 - 1 ? i / 2 : i / 2 + 1;
        for (int j = 0; j < limit2; j++)
        {
            int nextY = curY + dirY[dir];
            int nextX = curX + dirX[dir];
            board[nextY][nextX] = temp[idx];
            curY = nextY;
            curX = nextX;
            idx++;
        }
        dir = (dir + 1) % 4;
    }
}

int main()
{
    scanf("%d %d", &N, &M);
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= N; j++)
        {
            scanf("%d", &board[i][j]);
        }
    }
    sharkY = (N+1)/2;
    sharkX = (N+1)/2;
    while (M--)
    {
        int d, s;
        scanf("%d %d", &d, &s);
        removeBeads(d, s);
        flatten();
        moveBeads();
        while (1)
        {
            bool isThereExplosion = explodeBeads();
            if (!isThereExplosion)
            {
                break;
            }
            moveBeads();
        }
        changeBeads();
        backToBoard();
    }
    printf("%d", beads[1] + 2 * beads[2] + 3 * beads[3]);
    return 0;
}
profile
Grow up everyday
post-custom-banner

0개의 댓글