Game Develop

[Algorithm] Baekjoon 21610번 : 마법사 상어와 비바라기 본문

Algorithm/Baekjoon

[Algorithm] Baekjoon 21610번 : 마법사 상어와 비바라기

MaxLevel 2023. 9. 5. 14:47

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

 

21610번: 마법사 상어와 비바라기

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기

www.acmicpc.net

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
struct Node
{
    int y;
    int x;
};
 
int n, m, d, s;
int dir1[9][2= { {0,0}, {0,-1}, {-1,-1}, {-1,0}, {-1,1},{0,1},{1,1},{1,0},{1,-1} };
int dir2[4][2= { {-1,-1}, {-1,1}, {1,1}, {1,-1} };
int arr[51][51= { 0 };
bool check[51][51= { false };
vector<Node> clouds;
 
void makeClouds() 
{
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (check[i][j] == true)
            {
                check[i][j] = false;
                continue;
            }
 
            if (arr[i][j] >= 2)
            {
                clouds.push_back({ i,j });
                arr[i][j] -= 2;
            }
        }
    }
}
 
void move(int d, int s)
{
    for (int i = 0; i < clouds.size(); ++i)
    {
        int nextY = clouds[i].y + dir1[d][0* s;
        int nextX = clouds[i].x + dir1[d][1* s;
 
        if (nextY <= 0 || nextY > n)
        {
            nextY = nextY <= 0 ? n + nextY : nextY - n;
        }
 
        if (nextX <= 0 || nextX > n)
        {
            nextX = nextX <= 0 ? n + nextX : nextX - n;
        }
 
        arr[nextY][nextX] += 1;
        clouds[i].y = nextY;
        clouds[i].x = nextX;
        check[nextY][nextX] = true;
    }
 
    for (int i = 0; i < clouds.size(); ++i)
    {
        int curY = clouds[i].y;
        int curX = clouds[i].x;
 
        for (int j = 0; j < 4++j)
        {
            int nextY = curY + dir2[j][0];
            int nextX = curX + dir2[j][1];
 
            if (nextY <= 0 || nextY > n) continue;
            if (nextX <= 0 || nextX > n) continue;
 
            if (arr[nextY][nextX] >= 1) arr[curY][curX] += 1;
        }
    }
 
    clouds.clear();
    makeClouds();
}
 
int main(void)
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    cin >> n >> m;
 
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            cin >> arr[i][j];
        }
    }
 
    clouds = { {n - 1,1}, {n - 1,2}, {n,1}, {n,2} };
 
    for (int i = 0; i < m; ++i)
    {
        cin >> d >> s; // 방향, 거리
 
        move(d, s % n);
 
        int asdf = 0;
    }
 
    int answer = 0;
 
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            answer += arr[i][j];
        }
    }
 
    cout << answer;
 
    return 0;
}
cs

그냥 구현문제라 생각하면 된다. 인풋값들의 최대값도 큰편이 아니라 어떻게 짜든 진짜 어지간하면 시간초과로 걸릴일은 없다.

여기서 8방향에 대한 이동을 처리할 때, 8칸을 이동해야한다면 반복문 8번을 돌리는것보다는 내가 작성한것처럼 그냥 계산한번에 바로 좌표를 구할 수 있게 하는게 좋을 것 같다.

다른 문제에서는 효율성측면에서 컷트라인이 널널하단 보장이 없기 때문이다.