반응형

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

 

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

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

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 움직이는 방향별로 방향 배열을 만들어 모래의 위치를 기록할 수 있게 만듭니다.

 

2. for문을 통해서 각 위치에서 각각의 방향별로 모래의 이동을 구현합니다.

 

3. 토네이도가 0, 0의 좌표로 이동했을 때 for문을 종료시켜줍니다.

 

[ 소스코드 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include<iostream>
 
using namespace std;
 
int N;
int arr[500][500];
int ans;
int x;
int y;
int dx[4][9= {    //각 방향별로 방향 배열을 설정
    1,1,0,0,0,0,-1,-1,-2,    //좌
    -1,-1,0,0,0,0,1,1,2,    //우
    -1,1,-2,2,-1,1,-1,1,0,    //위
    -1,1,-2,2,-1,1,-1,1,0,    //아래
};
int dy[4][9= { 
    -1,1,-2,2,-1,1,-1,1,0,    //좌
    -1,1,-2,2,-1,1,-1,1,0,    //우
    1,1,0,0,0,0,-1,-1,-2,    //위
    -1,-1,0,0,0,0,1,1,2,    //아래
};
 
int ddy[4= { 0,0,-1,1 };
int ddx[4= { -1,1,0,0 };
 
void direction(int y, int x, int dir)
{
    int ret = 0;
 
    x = x + ddx[dir];
    y = y + ddy[dir];
 
    int out = 0;
    int move = 0;
    int tornado = 0;
 
    for (int i = 0; i < 9; i++) {    //모래의 이동 기록
        int yy = y + dy[dir][i];
        int xx = x + dx[dir][i];
        int temp = 0;
        if (i < 2) {
            temp = arr[y][x] / 100;
        }
        else if (i < 4) {
            temp = arr[y][x] / 50;
        }
        else if (i < 6) {
            temp = (arr[y][x] * 7)/100;
        }
        else if (i < 8) {
            temp = arr[y][x] / 10;
        }
        else {
            temp = arr[y][x] / 20;
        }
 
        if (yy >= 0 && yy < N && xx >= 0 && xx < N) {
            arr[yy][xx] += temp;
            tornado += temp;
        }
        else {
            tornado += temp;
            out += temp;
        }
    }
 
    move = arr[y][x] - tornado;    //알파 칸으로 움직일 모래의 양
    arr[y][x] = 0;
    ans += out;        //경계 밖으로 나간 모래의 양
 
    int yy = y + ddy[dir];
    int xx = x + ddx[dir];
    if (yy>=0&&yy<N&&xx>=0&&xx<N) {
        arr[yy][xx] += move;    //알파 칸이 경계 밖이 아니라면
    }
    else {                        //밖이라면
        ans += move;
    }
}
 
int main()
{
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            scanf("%d"&arr[i][j]);
        }
    }
 
    x = y = N / 2;
 
    for (int i = 1; i <= N; i++) {    //토네이도 이동
        if (y == 0 && x == 0) {
            break;
        }
        if (i % 2 == 0) {
            for (int j = 0; j < i; j++) {
                direction(y, x, 1);
                x += 1;
            }
            for (int j = 0; j < i; j++) {
                direction(y, x, 2);
                y -= 1;
            }
        }
        else {
            for (int j = 0; j < i; j++) {
                if (y == 0 && x == 0) {
                    break;
                }
                direction(y, x, 0);
                x -= 1;
            }
            if (y == 0 && x == 0) {
                break;
            }
            for (int j = 0; j < i; j++) {
                direction(y, x, 3);
                y += 1;
            }
        }
    }
 
    printf("%d", ans);
}
cs
반응형

+ Recent posts