[백준/BOJ] 백준 2206번 : 벽 부수고 이동하기
2020. 8. 15. 02:47ㆍ알고리즘 문제풀이
https://www.acmicpc.net/problem/2206
start에서 dest으로 가는 최단 거리를 구하는 함수를 만들었는데, 각 위치에서 벽을 부술 수 있는 횟수(0 또는 1)도 저장을 해, 벽을 부술 수 있다면 벽을 부수는 경우와 벽을 부수지 않는 경우를 모두 고려하였고, 벽을 부술 수 없다면 벽을 부수지 않는 경우만 고려하였다.
코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#include <string>
using namespace std;
int n, m;
vector<string> board;
int discoverd[1000][1000][2];
int depth[1000][1000][2];
int dx_dy[4][2] = { {0,-1},{-1,0},{0,1},{1,0} };
void Pre()
{
for (int i = 0; i < 1000; i++)
for (int j = 0; j < 1000; j++)
for (int k = 0; k < 2; k++)
discoverd[i][j][k] = 0;
}
//start에서 dest로 가는 최단 거리를 구한다
int Solve(pair<pair<int, int>, int> start, pair<int, int> dest)
{
discoverd[start.first.first][start.first.second][start.second] = 1;
depth[start.first.first][start.first.second][start.second] = 0;
queue<pair<pair<int, int>, int>> q;
q.push(start);
while (!q.empty())
{
pair<pair<int, int>, int> here = q.front();
q.pop();
//목적지에 도착 했을때 depth+1을 반환한다(시작하는 칸도 포함하므로)
if (here.first.first == dest.first && here.first.second == dest.second)
return depth[here.first.first][here.first.second][here.second] + 1;
//벽을 부수는 경우(벽을 부술 수 있는 횟수가 남아 있을때)
if (here.second > 0)
{
for (int i = 0; i < 4; i++)
{
pair<pair<int, int>, int> there = make_pair(make_pair(here.first.first + dx_dy[i][0], here.first.second + dx_dy[i][1]), here.second - 1);
if (there.first.first >= 0 && there.first.first < n && there.first.second >= 0 && there.first.second < m && discoverd[there.first.first][there.first.second][there.second] == 0)
{
discoverd[there.first.first][there.first.second][there.second] = 1;
depth[there.first.first][there.first.second][there.second] = depth[here.first.first][here.first.second][here.second] + 1;
q.push(there);
}
}
}
//벽을 부수지 않는 경우
for (int i = 0; i < 4; i++)
{
pair<pair<int, int>, int> there = make_pair(make_pair(here.first.first + dx_dy[i][0], here.first.second + dx_dy[i][1]), here.second);
if (there.first.first >= 0 && there.first.first < n && there.first.second >= 0 && there.first.second < m && discoverd[there.first.first][there.first.second][there.second] == 0 && board[there.first.first][there.first.second] == '0')
{
discoverd[there.first.first][there.first.second][there.second] = 1;
depth[there.first.first][there.first.second][there.second] = depth[here.first.first][here.first.second][here.second] + 1;
q.push(there);
}
}
}
return -1;
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
string temp;
Pre();
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> temp;
board.push_back(temp);
}
//(0,0)에서 (n-1,m-1)로 가는 최단 거리를 구하는 문제로 풀었다
//start에는 (0,0)의 위치뿐만 아니라 벽을 부술 수 있는 횟수도 저장했다
pair<pair<int, int>, int> start = make_pair(make_pair(0, 0), 1);
pair<int, int> dest = make_pair(n - 1, m - 1);
cout << Solve(start, dest);
return 0;
}
'알고리즘 문제풀이' 카테고리의 다른 글
[백준/BOJ] 백준 6087번 : 레이저 통신 (0) | 2020.08.15 |
---|---|
[백준/BOJ] 백준 3055번 : 탈출 (0) | 2020.08.15 |
[백준/BOJ] 백준 6497번 : 전력난 (0) | 2020.08.14 |
[백준/BOJ] 백준 1647번 : 도시 분할 계획 (0) | 2020.08.14 |
[백준/BOJ] 백준 2194번 : 유닛 이동시키기 (0) | 2020.08.14 |