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