반응형
https://www.acmicpc.net/problem/20057
 

20057번: 마법사 상어와 토네이도

마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을

www.acmicpc.net

1.문제설명

토네이도의 이동 방법은 단순 반복이기 때문에

반복문으로 구현할 수 있다.

 

토네이도에 따라 모래가 이동하는 것을 잘 구현해야 한다.

항상 모래가 퍼지는 방법은 동일한데

토네이도의 이동방향에 따라 다르다.

 

토네이도의 이동방향을 기준으로

현재 이동방향과 수직에 놓여있는지,

아니면 현재 이동방향의 2칸 앞에 있는지

현재 토네이도가 이동한 위치와 이동했던 방향을 기준으로

함수를 만들면 4방향에 대해서 모두 처리해주지 않아도 된다.

 

 

 

2.문제풀이코드 C++

#include <bits/stdc++.h>

using namespace std;

int N, sum, sand[500][500];

void Input();


int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};

bool inSand(int x, int y) {
    return (x >= 1 && x <= N && y >= 1 && y <= N);
}

void flySand(int x, int y, int dir) {
    int nx = x + dx[dir] * 2;
    int ny = y + dy[dir] * 2;
    int sum = 0;

    int num = int(sand[x][y] * 0.05);
    sum += num;
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }

    //수직

    num = int(sand[x][y] * 0.07);
    sum += num;
    nx = x + dx[(dir + 1) % 4];
    ny = y + dy[(dir + 1) % 4];
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }


    num = int(sand[x][y] * 0.07);
    sum += num;
    nx = x + dx[(dir + 3) % 4];
    ny = y + dy[(dir + 3) % 4];
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }


    num = int(sand[x][y] * 0.02);
    sum += num;
    nx = x + dx[(dir + 1) % 4] * 2;
    ny = y + dy[(dir + 1) % 4] * 2;
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }


    num = int(sand[x][y] * 0.02);
    sum += num;
    nx = x + dx[(dir + 3) % 4] * 2;
    ny = y + dy[(dir + 3) % 4] * 2;
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }


    //수직

    num = int(sand[x][y] * 0.1);
    sum += num;
    nx = x + dx[(dir + 1) % 4] + dx[dir];
    ny = y + dy[(dir + 1) % 4] + dy[dir];
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }


    num = int(sand[x][y] * 0.1);
    sum += num;
    nx = x + dx[(dir + 3) % 4] + dx[dir];
    ny = y + dy[(dir + 3) % 4] + dy[dir];
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }


    //수직\

    num = int(sand[x][y] * 0.01);
    sum += num;
    nx = x + dx[(dir + 1) % 4] - dx[dir];
    ny = y + dy[(dir + 1) % 4] - dy[dir];
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }


    num = int(sand[x][y] * 0.01);
    sum += num;
    nx = x + dx[(dir + 3) % 4] - dx[dir];
    ny = y + dy[(dir + 3) % 4] - dy[dir];
    if (inSand(nx, ny)) {
        sand[nx][ny] += num;
    }

    nx = x + dx[dir];
    ny = y + dy[dir];
    if (inSand(nx, ny)) {
        sand[nx][ny] += sand[x][y] - sum;
    }

    sand[x][y] = 0;

}


void tornadoMove() {
    int x = N / 2 + 1, y = N / 2 + 1;
    int dir = 0;
    int moveBlocks = 1;
    int cnt = 0;

//    while(!(x==1 && y==1)){
    while (1) {
        for (int i = 0; i < moveBlocks; i++) {
            x += dx[dir];
            y += dy[dir];
            flySand(x, y, dir);

            if (x == 1 && y == 1) return;
        }
        cnt++;
        dir = (dir + 1) % 4;
        if (cnt == 2) {
            moveBlocks++;
            cnt = 0;
        }

    }
}


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


    Input();
    tornadoMove();

    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            sum -= sand[i][j];
        }
    }

    cout << sum << '\n';
}

void Input() {
    cin >> N;

    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            cin >> sand[i][j];
            sum += sand[i][j];
        }
    }
}
반응형

+ Recent posts