1
1
// Authored by : windowdong11
2
- // Co-authored by : -
3
- // http://boj.kr/472174a0b78b4e9e8285a1f4406c9a4d
2
+ // Co-authored by : BaaaaaaaaaaarkingDog
3
+ // http://boj.kr/aedfb7aa7cdb43c4862ce55cc140c48b
4
4
#include < bits/stdc++.h>
5
5
using namespace std ;
6
6
#define X first
7
7
#define Y second
8
8
9
- template <class Ty , class Tx >
10
- bool isInArea2d (pair<Ty, Tx> cur, pair<Ty, Tx> minSize, pair<Ty, Tx> maxSize) {
11
- return minSize.first <= cur.first && cur.first < maxSize.first
12
- && minSize.second <= cur.second && cur.second < maxSize.second ;
13
- }
14
-
15
- pair<int , int > ways4[] = {
16
- {0 , 1 },
17
- {1 , 0 },
18
- {0 , -1 },
19
- {-1 , 0 },
20
- };
9
+ int dx[4 ] = {0 ,1 ,0 ,-1 };
10
+ int dy[4 ] = {1 ,0 ,-1 ,0 };
21
11
22
12
char board[1000 ][1000 ];
23
13
pair<int , int > boardEnd;
24
- int cost [1000 ][1000 ][2 ];
25
- // cost [x][y][0] : 벽을 하나도 부수지 않고 (x,y)까지 오는데 걸리는 비용
26
- // cost [x][y][1] : 벽을 하나만 부수고 (x,y)까지 오는데 걸리는 비용, (x,y)가 벽이라서 부수는 경우 포함
14
+ int dist [1000 ][1000 ][2 ];
15
+ // dist [x][y][0] : 벽을 하나도 부수지 않고 (x,y)까지 오는데 걸리는 비용
16
+ // dist [x][y][1] : 벽을 하나만 부수고 (x,y)까지 오는데 걸리는 비용, (x,y)가 벽이라서 부수는 경우 포함
27
17
int n, m;
28
18
19
+ bool OOB (int x, int y){
20
+ return x < 0 || x >= n || y < 0 || y >= m;
21
+ }
22
+
29
23
int bfs () {
30
24
for (int i = 0 ; i < n; ++i)
31
25
for (int j = 0 ; j < m; ++j)
32
- cost [i][j][0 ] = cost [i][j][1 ] = -1 ;
33
- cost [0 ][0 ][0 ] = cost [0 ][0 ][1 ] = 1 ;
34
- queue<pair< bool , pair< int , int > >> q;
35
- q.push ({ false , { 0 , 0 } });
26
+ dist [i][j][0 ] = dist [i][j][1 ] = -1 ;
27
+ dist [0 ][0 ][0 ] = dist [0 ][0 ][1 ] = 1 ;
28
+ queue<tuple< int , int , int >> q;
29
+ q.push ({0 , 0 , 0 });<
10000
/div>
36
30
while (!q.empty ()) {
37
- bool broken = q. front (). first ;
38
- pair< int , int > cur = q.front (). second ;
39
- int nextCost = cost[cur. X ][cur. Y ][broken] + 1 ;
31
+ int x, y, broken ;
32
+ tie (x, y, broken) = q.front ();
33
+ if (x == n- 1 && y == m- 1 ) return dist[x][y ][broken];
40
34
q.pop ();
41
- for (int i = 0 ; i < 4 ; ++i) {
42
- pair<int , int > next = { cur.X + ways4[i].X , cur.Y + ways4[i].Y };
43
- if (next == boardEnd) return nextCost;
44
- if (isInArea2d (next, { 0 , 0 }, { n, m })) {
45
- if (broken) {
46
- if (board[next.X ][next.Y ] == ' 0' && cost[next.X ][next.Y ][1 ] == -1 ) {
47
- cost[next.X ][next.Y ][1 ] = nextCost;
48
- q.push ({ 1 , next });
49
- }
50
- }
51
- else {
52
- if (board[next.X ][next.Y ] == ' 0' && cost[next.X ][next.Y ][0 ] == -1 ) {
53
- cost[next.X ][next.Y ][0 ] = cost[next.X ][next.Y ][1 ] = nextCost;
54
- q.push ({ 0 , next });
55
- }
56
- else if (board[next.X ][next.Y ] == ' 1' && cost[next.X ][next.Y ][1 ] == -1 ) {
57
- cost[next.X ][next.Y ][1 ] = nextCost;
58
- q.push ({ 1 , next });
59
- }
60
- }
61
- }
35
+ int nextdist = dist[x][y][broken] + 1 ;
36
+ for (int dir = 0 ; dir < 4 ; ++dir) {
37
+ int nx = x + dx[dir];
38
+ int ny = y + dy[dir];
39
+ if (OOB (nx, ny)) continue ;
40
+ if (board[nx][ny] == ' 0' && dist[nx][ny][broken] == -1 ) {
41
+ dist[nx][ny][broken] = nextdist;
42
+ q.push ({nx, ny, broken});
43
+ }
44
+ // (nx, ny)를 부수는 경우
45
+ if (!broken && board[nx][ny] == ' 1' && dist[nx][ny][1 ] == -1 ) {
46
+ dist[nx][ny][1 ] = nextdist;
47
+ q.push ({nx, ny, 1 });
48
+ }
62
49
}
63
50
}
64
51
return -1 ;
@@ -68,11 +55,9 @@ int main(void) {
68
55
ios_base::sync_with_stdio (false );
69
56
cin.tie (0 ); cout.tie (0 );
70
57
cin >> n >> m;
71
- boardEnd = { n - 1 , m - 1 };
72
58
for (int i = 0 ; i < n; ++i)
73
59
for (int j = 0 ; j < m; ++j)
74
60
cin >> board[i][j];
75
- if (n == 1 && m == 1 ) cout << 1 ;
76
- else cout << bfs ();
61
+ cout << bfs ();
77
62
return 0 ;
78
63
}
0 commit comments