728x90
https://www.acmicpc.net/problem/1261
사실 이 문제는 분류가 다익스트라 알고리즘으로 분류되어있었는데, 그 알고리즘에 대해서 몰라도 풀수 있다.
전형적인 bfs문제는 아니고 다이나믹 프로그래밍의 캐시 개념만 조금 쓰면 풀 수 있다.
어떻게 보면 최단 경로 문제이기 때문에 (빙빙 돌아가면서 벽을 부숴가면서 미로를 탐색하진 않을것 아닌가?) bfs를 쓰는 것은 당연한 것이고,
그렇다면 caching은 어떻게 적용할 것인가?
우선 2차원 dp 배열을 만든다. 각각의 원소는 적당히 큰값으로 초기화를 해주고,
첫 dp[0][0] = 0으로 초기화를 한 이후에, map에서 원소의 값이 0이냐 1이냐를 파악한 후, dp값을 갱신해 가면서, 만약 갱신이 되었다면 그 경우에만 다시 bfs를 돌리면 된다. 이미 최소의 dp값이 있는데 그것보다 더 큰 값을 들고 오면 그 경로는 더 탐색을 안해도 되기 때문이다.
<소스 코드>
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
|
#include <iostream>
#include <queue>
#include <string>
using namespace std;
int n,m,answer;
int map[100][100];
int dp[100][100];
int dy[4] = {1,-1,0,0};
int dx[4] = {0,0,1,-1};
void bfs(int a, int b){
queue<pair<int,int>> q;
q.push(make_pair(a,b));
dp[a][b]=0;
while(!q.empty()){
int x = q.front().first;
int y = q.front().second;
// cout<<x<<" "<<y<<" "<<dp[y][x]<<"\n";
q.pop();
for(int i=0; i<4;i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx>=0 && ny>=0 && nx < m && ny<n){
if(map[ny][nx]==0){
if(dp[ny][nx]>dp[y][x]){
dp[ny][nx]=dp[y][x];
q.push(make_pair(nx,ny));
}
}
else if (map[ny][nx]==1){
if(dp[ny][nx]>dp[y][x]+1){
dp[ny][nx]=dp[y][x]+1;
q.push(make_pair(nx,ny));
}
}
}
}
}
}
int main(void){
answer = 999999999;
cin>>m>>n; //m이 가로길이 n이 세로길이
for(int i=0; i<n; i++){
string s;
cin>>s;
for(int j=0; j<m; j++){
map[i][j] = s[j]-'0';
dp[i][j] = 999999999;
}
}
bfs(0,0);
cout<<dp[n-1][m-1];
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
'알고리즘 > 백준' 카테고리의 다른 글
백준 17779 - 게리맨더링2 - 시뮬레이션 (c++) (0) | 2020.03.04 |
---|---|
백준 13335 트럭 - 큐 2개를 활용하자 c++ (0) | 2020.02.25 |
백준 2143 두 배열의 합 - 단순 브루트포스 c++ (0) | 2020.02.18 |
투 포인터 알고리즘, 슬라이딩 알고리즘 (0) | 2020.02.13 |
백준 1182 부분수열의 합- 재귀 브루트포스 (c++) (0) | 2020.02.13 |