[백준] 20057번

Jeanine·2022년 4월 22일
0

baekjoon

목록 보기
90/120
post-thumbnail

💻 C++ 기반

마법사 상어와 토네이도
https://www.acmicpc.net/problem/20057

✔️ '토네이도의 이동 -> 모래의 이동' 구조로 코드 구현
✔️ 토네이도의 이동같은 경우에는, N에 따라 화살표의 개수와 각 화살표의 길이가 달라지는 규칙을 파악했음
✔️ 모래의 이동같은 경우에는, 0번 방향 기준으로 먼저 각 모래가 흩어지는 칸을 찾아주기 -> 다른 방향의 경우에는 각 방향에다가 새로운 방향까지 더하기를 해주고 4로 나눈 나머지를 이용

#include <cstdio>

#define MAX_N 500

using namespace std;

int N;
int A[MAX_N][MAX_N];
int dy[4] = {0, 1, 0, -1}; //서남동북
int dx[4] = {-1, 0, 1, 0};
int outside = 0;

void checkOutside(int nextY, int nextX, int amount)
{
    if (nextY < 1 || nextY > N || nextX < 1 || nextX > N)
    {
        outside += amount;
    }
    else
    {
        A[nextY][nextX] += amount;
    }
}

void moveDust(int tornadoY, int tornadoX, int dir)
{
    int nextY, nextX;
    int amount = 0;
    /* 5% */
    nextY = tornadoY + 2 * dy[dir];
    nextX = tornadoX + 2 * dx[dir];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.05));
    amount += int(A[tornadoY][tornadoX] * 0.05);
    
    /* 10% */
    nextY = tornadoY + dy[dir] + dy[(dir + 1) % 4];
    nextX = tornadoX + dx[dir] + dx[(dir + 1) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.1));
    nextY = tornadoY + dy[dir] + dy[(dir + 3) % 4];
    nextX = tornadoX + dx[dir] + dx[(dir + 3) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.1));
    amount += int(A[tornadoY][tornadoX] * 0.1) * 2;

    /* 7% */
    nextY = tornadoY + dy[(dir + 1) % 4];
    nextX = tornadoX + dx[(dir + 1) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.07));
    nextY = tornadoY + dy[(dir + 3) % 4];
    nextX = tornadoX + dx[(dir + 3) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.07));
    amount += int(A[tornadoY][tornadoX] * 0.07) * 2;

    /* 2% */
    nextY = tornadoY + 2 * dy[(dir + 1) % 4];
    nextX = tornadoX + 2 * dx[(dir + 1) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.02));
    nextY = tornadoY + 2 * dy[(dir + 3) % 4];
    nextX = tornadoX + 2 * dx[(dir + 3) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.02));
    amount += int(A[tornadoY][tornadoX] * 0.02) * 2;

    /* 1% */
    nextY = tornadoY + dy[(dir + 2) % 4] + dy[(dir + 1) % 4];
    nextX = tornadoX + dx[(dir + 2) % 4] + dx[(dir + 1) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.01));
    nextY = tornadoY + dy[(dir + 2) % 4] + dy[(dir + 3) % 4];
    nextX = tornadoX + dx[(dir + 2) % 4] + dx[(dir + 3) % 4];
    checkOutside(nextY, nextX, int(A[tornadoY][tornadoX] * 0.01));
    amount += int(A[tornadoY][tornadoX] * 0.01) * 2;

    /* alpha */
    int rest = A[tornadoY][tornadoX] - amount;
    nextY = tornadoY + dy[dir];
    nextX = tornadoX + dx[dir];
    checkOutside(nextY, nextX, rest);

    A[tornadoY][tornadoX] = 0;
}

int main()
{
    scanf("%d", &N);
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= N; j++)
        {
            scanf("%d", &A[i][j]);
        }
    }

    int tornadoY = N / 2 + 1;
    int tornadoX = N / 2 + 1;
    int dir = 0;
    int cntArrows = (N - 1) * 2 + 1;
    for (int i = 0; i < cntArrows; i++)
    {
        int lenOfArrow = 2 + i / 2;
        for (int j = 1; j < lenOfArrow; j++)
        {
            tornadoY = tornadoY + dy[dir];
            tornadoX = tornadoX + dx[dir];
            moveDust(tornadoY, tornadoX, dir);
        }
        dir = (dir + 1) % 4;
    }
    printf("%d", outside);
    return 0;
}
profile
Grow up everyday

0개의 댓글