BOJ::2206 벽 부수고 이동하기
https://www.acmicpc.net/problem/2206
이 문제 푸는데 정말 오래 걸렸다.
https://www.acmicpc.net/problem/2178 와 같은 미로찾기의 상위 문제
처음에는 뚫을 수 있는 벽에 대해서만 벽을 뚫어 bfs한 결과 중 최소값을 출력하려고 했는데 계속 시간 초과가 났다. 그래서 다른 방법으로 3차원배열 d를 만들어 d[][][0]은 벽을 뚫지 않은 상태, d[][][1]은 벽을 뚫은 상태 로 생각하고 풀었다.
이문제를 풀 수 있으면
https://www.acmicpc.net/problem/14442 벽부수고 이동하기 2 도 비교적 쉽게 풀 수 있다.
<C++>
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 | #include <stdio.h> #define MIN(a, b) ((a)<(b))?(a):(b) #define SZ 1000 #define QSZ 1000001 // 큐사이즈 //좌표 저장용 struct P { int x, y; bool used;//벽 뚫기 사용했는지 안했는지 확인용 P() {} P(int x, int y, bool used) :x(x), y(y), used(used) {} }; int n, m; int map[SZ][SZ]; int d[SZ][SZ][2]; int dx[] = { 0,0,1,-1 }; int dy[] = { 1,-1,0,0 }; P q[QSZ]; int rear, front; void push(P p) { rear = (rear + 1) % QSZ; q[rear] = p; } P pop() { front = (front + 1) % QSZ; return q[front]; } bool isEmpty() { return rear == front; } void bfs() { //d배열 초기화 d[0][0][0] = 1; d[0][0][1] = 1; push(P(0, 0, false)); while (!isEmpty()) { P p = pop(); int x = p.x; int y = p.y; bool used = p.used; for (int i = 0; i < 4; i++) { int ax = x + dx[i]; int ay = y + dy[i]; if (ax >= 0 && ay >= 0 && ax < n&&ay < m) { //길일때 if (map[ax][ay] == 0) { //벽뚫기 사용하지 않은 경우 if (!used) { if (d[ax][ay][0] == 0 || d[ax][ay][0] > d[x][y][0] + 1) { d[ax][ay][0] = d[x][y][0] + 1; push(P(ax, ay, false)); } } //벽뚫기 사용한 경우 if (d[ax][ay][1] == 0 || d[ax][ay][1] > d[x][y][1] + 1) { d[ax][ay][1] = d[x][y][1] + 1; push(P(ax, ay, true)); } } else { //벽을 뚫는 경우 if (!used) { if (d[ax][ay][1] == 0 || d[ax][ay][1] > d[x][y][0] + 1) { d[ax][ay][1] = d[x][y][0] + 1; push(P(ax, ay, true)); } } } } } } } int main() { scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { scanf(" %c", &map[i][j]); map[i][j] -= '0'; } } bfs(); int res1 = d[n - 1][m - 1][0]; //벽을 안뚫었을때 최소값 int res2 = d[n - 1][m - 1][1]; //벽을 뚫었을때 최소값 int res = 0; if (res1 != 0 && res2 != 0) { res = MIN(res1, res2); } else if (res1 == 0) { res = res2; } else if (res2 == 0) { res = res1; } if (res == 0) res = -1; printf("%d\n", res); } | cs |
'BOJ::문제풀이' 카테고리의 다른 글
2293 동전 1 (0) | 2018.01.01 |
---|---|
2217 로프 (0) | 2018.01.01 |
2193 이친수 (0) | 2018.01.01 |
2178 미로 탐색 (0) | 2018.01.01 |
2156 포도주 시식 (0) | 2018.01.01 |