본문 바로가기
코딩/문제풀이-백준

백준 19237번 - 어른 상어 (C++)

by 남대현 2021. 8. 20.
반응형

문제

 

해결 방법

문제에 써있는 그대로 구현하는 문제이다. 때문에 좌표, 자신의 규칙을 담는 4x4 2차원 배열[방향][우선순위], 순서, 방향을 담는 shark 클래스를 만들어서 진행하였다.

아쉬웠던 점

없다.

코드

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
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <string.h>
#include <tuple>
using namespace std;
 
int UDLRy[4= {0,0,-1,1};
int UDLRx[4= {-1,1,0,0};
 
class Shark
{
public:
    int X, Y;
    int Dir;
    int Rule[4][4];
    int Num;
};
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    int N, M, K;
    pair<intint> Map[20][20]; //상어번호, 냄새 지속시간
    cin >> N >> M >> K;
    vector<Shark> SharkVec(M);
 
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
        {
            int a;
            cin >> a;
            if (a != 0)
            {
                Map[i][j].first = a;
                Map[i][j].second = K;
                SharkVec[a - 1].X = i;
                SharkVec[a - 1].Y = j;
                SharkVec[a - 1].Num = a;
            }
            else
            {
                Map[i][j].first = 0;
                Map[i][j].second = 0;
            }
        }
 
    for (int i = 0; i < M; ++i)
        cin >> SharkVec[i].Dir;
 
    for (int i = 0; i < M; ++i)
        for(int j = 0 ; j < 4++j)
            for (int k = 0; k < 4++k)
                cin >> SharkVec[i].Rule[j][k];
    
    int Time = 0;
    while (SharkVec.size() != 1)
    {
        Time++;
        if (Time == 1001)
        {
            cout << "-1";
            return 0;
        }
 
        //상어 이동
        for (auto &i : SharkVec)
        {
            bool Check = true;
            for (int j = 0; j < 4++j)
            {
                int Fx = i.X + UDLRx[i.Rule[i.Dir - 1][j] - 1];
                int Fy = i.Y + UDLRy[i.Rule[i.Dir - 1][j] - 1];
                if (Fx < 0 || Fx >= N || Fy < 0 || Fy >= N)
                    continue;
 
                if (Map[Fx][Fy].second == 0)
                {
                    i.X = Fx;
                    i.Y = Fy;
                    Check = false;
                    i.Dir = i.Rule[i.Dir - 1][j];
                    break;
                }
            }
            if (Check)
            {
                for (int j = 0; j < 4++j)
                {
                    int Fx = i.X + UDLRx[i.Rule[i.Dir - 1][j] - 1];
                    int Fy = i.Y + UDLRy[i.Rule[i.Dir - 1][j] - 1];
                    if (Fx < 0 || Fx >= N || Fy < 0 || Fy >= N)
                        continue;
 
                    if (Map[Fx][Fy].first == i.Num)
                    {
                        i.X = Fx;
                        i.Y = Fy;
                        i.Dir = i.Rule[i.Dir - 1][j];
                        break;
                    }
                }
            }
        }
 
        //모든 좌표의 냄새 유효시간 감소
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
            {
                if (Map[i][j].second == 1)
                    Map[i][j].first = 0;
 
                if (Map[i][j].second != 0)
                    Map[i][j].second--;
            }
 
        //이동한 결과를 다시 순회하며 적용. 이때 중복은 삭제.
        vector<Shark>::iterator iter = SharkVec.begin();
        for (;iter != SharkVec.end();)
        {
            if (Map[iter->X][iter->Y].second == K)
            {
                iter = SharkVec.erase(iter);
                continue;
            }
 
            Map[iter->X][iter->Y].first = iter->Num;
            Map[iter->X][iter->Y].second = K;
            iter++;
        }
 
    }
 
    cout << Time;
}
cs

특이점은 상어들이 동시에 진행하는 판정이기 때문에, 상어들만 먼저 이동규칙에 따라서 상어 클래스 내부의 xy를 변경해주고, 이후에 상어들을 모두 담은 벡터를 순회하며 맵에 이동결과를 적용시켜준다. 또한, 이때 상어들의 위치가 중복되었다면 순번이 더 큰 상어들은 erase를 통하여 삭제시켜준다.

반응형

댓글