1
- // Authored by : BaaaaaaaaaaarkingDog
1
+ // Authored by : H2ll0World
2
2
// Co-authored by : -
3
- // http://boj.kr/****************
3
+ // http://boj.kr/b3c853360b644b44b76397387d1062c0
4
4
#include < bits/stdc++.h>
5
5
using namespace std ;
6
6
7
- int main (void ){
7
+ int dy[] = {-1 , 0 , 1 , 0 };
8
+ int dx[] = {0 , 1 , 0 , -1 };
9
+ pair<int , int > board[400 ][400 ]; // (냄새 지속시간, 냄새 주인)
10
+ int preBoard[400 ][400 ]; //
11
+ pair<int , int > pos[1001 ]; // 상어의 위치
12
+ bool live[1001 ]; // 상어의 생존여부
13
+ int curDir[1001 ]; // 상어의 방향
14
+ int dirPriority[1001 ][4 ][4 ]; // 상어의 방향 우선순위
15
+
16
+ // 북쪽을 기준으로 시계방향으로 변함
17
+ int changeDir (int dir){
18 + if (dir == 1 )
19
+ return 0 ;
20
+ else if (dir == 2 )
21
+ return 2 ;
22
+ else if (dir == 3 )
23
+ return 3 ;
24
+ else if (dir == 4 )
25
+ return 1 ;
26
+ }
27
+
28
+ int main (){
8
29
ios::sync_with_stdio (0 );
9
30
cin.tie (0 );
10
-
11
- }
31
+
32
+ for (int i = 0 ; i < 400 ; ++i)
33
+ fill (board[i], board[i] + 400 , std::make_pair (0 , 0 ));
34
+
35
+ for (int i = 0 ; i < 400 ; ++i)
36
+ fill (preBoard[i], preBoard[i] + 400 , -1 );
37
+
38
+ fill (live, live + 1001 , true );
39
+
40
+ int n, m, k; // n : 격자의 크기 // m : 상어의 숫자 // k : 냄새의 지속 시간
41
+ cin >> n >> m >> k;
42
+
43
+ int tmp;
44
+ for (int i = 0 ; i < n; i++)
45
+ for (int j = 0 ; j < n; j++){
46
+ cin >> tmp;
47
+ if (tmp != 0 ) {
48
+ pos[tmp] = make_pair (i, j);
49
+ board[i][j].first = k; //
50
+ board[i][j].second = tmp;
51
+ }
52
+ }
53
+
54
+ for (int i = 1 ; i <= m; i++){
55
+ cin >> tmp;
56
+ curDir[i] = changeDir (tmp);
57
+ }
58
+
59
+ for (int i = 1 ; i <= m; i++)
60
+ for (int j = 1 ; j <= 4 ; j++)
61
+ for (int z = 0 ; z < 4 ; z++){
62
+ cin >> tmp;
63
+ dirPriority[i][changeDir (j)][z] = changeDir (tmp);
64
+ }
65
+
66
+ int dir;
67
+ int ny, nx;
68
+ int liveCnt = m;
69
+ int time ;
70
+ for (time = 1 ; time <= 1002 ; time ++){
71
+ // 상어 이동
72
+ if (liveCnt == 1 ) break ;
73
+ for (int i = 1 ; i <= m; i++){
74
+ if (live[i] == 0 ) continue ; // 나간 경우
75
+
76
+ int j;
77
+ bool fir = 1 ; // 자신의 냄새
78
+ int myY, myX;
79
+ int myDir;
80
+ for (j = 0 ; j < 4 ; j++){
81
+ dir = dirPriority[i][curDir[i]][j];
82
+ ny = pos[i].first + dy[dir]; nx = pos[i].second + dx[dir];
83
+
84
+ if (ny < 0 || ny >= n || nx < 0 || nx >= n) // OOB : Out of Bound
85
+ continue ;
86
+
87
+ if (board[ny][nx].first == time + k && time > preBoard[ny][nx]){ // 1. 냄새가 없는 칸이 있는 경우, 우선순위가 높은 상어와 같이 방문한 경우
88
+ // 우선순위가 높은 상어가 있음
89
+ live[i] = 0 ; // 쫓겨남
90
+ liveCnt--;
91
+ break ;
92
+ }else if (time <= board[ny][nx].first ){ // 냄새가 남아있어서 방문 X
93
+ if (fir && board[ny][nx].second == i){ // 그 냄새가 자신의 것인 경우
94
+ myY = ny; myX = nx;
95
+ myDir = dir;
96
+ fir = 0 ;
97
+ }
98
+ continue ;
99
+ }
100
+ preBoard[ny][nx] = board[ny][nx].first ;
101
+ board[ny][nx].first = time + k;
102
+ board[ny][nx].second = i;
103
+
104
+ pos[i].first = ny;
105
+ pos[i].second = nx;
106
+ curDir[i] = dir;
107
+
108
+ break ;
109
+ }
110
+ if (j == 4 ){ // 2. 냄새가 없는 칸이 없는 경우 -> 자신의 냄새로 이동
111
+ preBoard[myY][myX] = board[myY][myX].first ;
112
+ board[myY][myX].first = time + k;
113
+ pos[i].first = myY; pos[i].second = myX;
114
+ curDir[i] = myDir;
115
+ }
116
+ }
117
+ }
118
+
119
+ time --;
120
+ if (time > 1000 ){
121
+ cout << -1 << ' \n ' ;
122
+ return 0 ;
123
+ }
124
+
125
+ cout << time << ' \n ' ;
126
+ return 0 ;
127
+ }
0 commit comments