코딩공작소
[백준]벽부수고이동하기 본문
https://www.acmicpc.net/problem/2206
2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다. 만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 한 개 까지 부수고 이동
www.acmicpc.net
나름 신박한 문제 !
일단 최소거리를 구하는것이라서 bfs라고 생각했고 등산로 조성과 비슷한 느낌이라서 flag를 통해 벽을 부순 여부를 유지하고 변경해가며 진행을 해줬다. 문제점은 등산로조성은 dfs완탐으로 벽을 부순여부가 다른 길에 영향을 주지 않지만 해당문제의 경우 다른 길에게 영향을 줬다. (예를 들어 벽을 부수고 간길에 대해 벽을 부수지 않고 온길이 그 길로 갈 수 없다)
이것에 대한 해결방안은 방문배열을 3차원으로 선언해서 부수고 온놈들끼리(는 최소를 찾는것이라 서로 영향 X), 혹은 안부수고 온놈들끼리 구분해줘서 서로 영향을 미치지 않게 해주는 것! bfs에서 다른곳에 영향을 주지 않으려면 다중배열로 처리해야하나 부다.
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
|
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct Stone{
int r, c, flag;
};
int N, M;
int map[1001][1001], dis[1001][1001][2]; //메인 아이디어!!
int dr[] = { -1,1,0,0 }, dc[] = { 0,0,-1,1 };
queue<Stone> q;
void solve() {
while (!q.empty()) {
int r = q.front().r, c = q.front().c;
int isCrush = q.front().flag; q.pop();
for (int i = 0; i < 4; i++) {
int nr = r + dr[i], nc = c + dc[i];
if (nr <= 0 || nc <= 0 || nr > N || nc > M || dis[nr][nc][isCrush] != 0) continue;
if (map[nr][nc] == 0) { //벽없음.
dis[nr][nc][isCrush] = dis[r][c][isCrush] + 1; //현상황 유지로 q에 넣음.
q.push({ nr,nc,isCrush });
if (nr == N && nc == M) { printf("%d\n", dis[nr][nc][isCrush]); return; }
}
else if (map[nr][nc] == 1 && isCrush == 0) { //벽 부수기 가능.
dis[nr][nc][1] = dis[r][c][isCrush] + 1;
q.push({ nr,nc,1 });//벽을 부숨.
}
}
}
printf("-1\n"); //실패하는 경우
}
int main()
{
cin >> N >> M;
for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) scanf_s("%1d",&map[i][j]);
if (N == 1 && M == 1) { printf("1\n"); return 0; } //항상 이런 상황 생각해보기.
q.push({ 1,1,0 }); dis[1][1][0] = 1;
solve();
return 0;
}
|
cs |
'알고리즘 > 그래프' 카테고리의 다른 글
[백준]아기상어(3) (0) | 2019.09.28 |
---|---|
[SWEA]탈주범검거 (0) | 2019.09.28 |
[백준]게리맨더링 (0) | 2019.09.21 |
[백준]다리만들기2 (0) | 2019.09.20 |
[백준]두동전 (0) | 2019.09.17 |