본문 바로가기
알고리즘/백준 문제

20057 - 마법사 상어와 토네이도

by HDobby 2023. 7. 12.

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

 

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

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

www.acmicpc.net

과정

  1. 토네이도는 좌, 하, 우, 상 순서로 움직인다.
  2. 다른 방향으로 2번 움직이고 나면 움직이는 칸수가 한칸 증가한다.
  3. 토네이도가 움직일때 밀어내는 방향을 배열로 저장하면 편하다.
  4. y -> a로 밀리는 양은 55%가 아닌 소수점 연산을 진행한 만큼 움직이고 남은 모래이다. 10의 경우 2만큼 밀려서 8만큼 a로 가게된다.
  5. 밖으로 빠져나가는 건 토네이도로 밀렸을 때도 포함 해줘야 한다.

코드

#include<iostream>

using namespace std;

int N;
int A[501][501];

int my[4] = { 0, 1, 0, -1 };
int mx[4] = { -1, 0, 1, 0 };

int tmy[4][10] = { { -1, 1, -1, 1, -1, 1, -2, 2, 0, 0},
                    { 0, 0, 1, 1, 2, 2, 1, 1, 3, 2}, 
                    {-1, 1, -1, 1, -1, 1, -2, 2, 0, 0},
                    { 0, 0, -1, -1, -2, -2, -1, -1, -3, -2} };
 
int tmx[4][10] = { { 0, 0, -1, -1, -2, -2, -1, -1, -3, -2} ,
                    { -1, 1, -1, 1, -1, 1, -2, 2, 0, 0 },
                    { 0, 0, 1, 1, 2, 2, 1, 1, 3, 2},
                    { -1, 1, -1, 1, -1, 1, -2, 2, 0, 0 } };

int tornado[10] = { 1, 1, 7, 7, 10, 10, 2, 2, 5, 0};

void input(){
    cin>>N;
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            cin>>A[i][j];
        }
    }
}

int move_sand(int m, int y, int x){
    int ny = y+my[m], nx=x+mx[m];
    int out = 0, sand = A[ny][nx], cnt = 0;
    A[ny][nx]=0;

    if(sand == 0)
        return 0;

    for(int i=0;i<10;++i){
        ny = y+tmy[m][i];
        nx = x+tmx[m][i];
        int swept = sand * tornado[i] / 100;
        cnt += swept;

        if(ny<0||nx<0||ny>=N||nx>=N){
            if(i == 9)
                out += sand - cnt;
            
            else
                out += swept;
        }
            
        else{
            if(i == 9)
                A[ny][nx] += sand - cnt;

            else
                A[ny][nx] += swept;
        }
            
    }

    return out;
}

int calc(){
    int answer = 0;
    int move_cnt = 1;
    int y=N/2, x=N/2;
    while(1){
        for(int i=0;i<4;++i){
            for(int j=0;j<move_cnt;++j){
                answer += move_sand(i, y, x);
                
                y+=my[i];
                x+=mx[i];

                if(y==0 && x==0)
                    return answer;
            }
            
            if(i%2 == 1)
                ++move_cnt;
        }
    }
}

void solution(){
    int answer = 0;

    answer = calc();
    
    cout<<answer<<'\n';
}

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

    input();
    solution();

    return 0;
}

728x90

'알고리즘 > 백준 문제' 카테고리의 다른 글

19949 - 영재의 시험  (0) 2023.07.13
19591 - 독특한 계산기  (0) 2023.07.13
8980 - 택배  (0) 2023.07.12
9527 - 1의 개수 세기  (0) 2023.07.07
1781 - 컵라면  (0) 2023.07.03

댓글