일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- algorithm
- 알고리즘
- 프로그래머스
- 문제풀이
- algogritim
- 감상문
- 데이터베이스
- Programmers
- LeetCode
- 네트워크
- OS
- db
- swea
- 자료구조
- Database
- 법의학
- D2
- language
- cs
- 백준
- network
- BOJ
- Computer Science
- c++
- SW Expert Academy
- D3
- 독서
- 재테크/투자
- data structure
- 운영체제
Archives
- Today
- Total
선택은 나의 것
[BOJ 백준] 17090번 미로 탈출하기 본문
문제
BOJ 17090 : https://www.acmicpc.net/problem/17090
17090번: 미로 탈출하기
크기가 N×M인 미로가 있고, 미로는 크기가 1×1인 칸으로 나누어져 있다. 미로의 각 칸에는 문자가 하나 적혀있는데, 적혀있는 문자에 따라서 다른 칸으로 이동할 수 있다. 어떤 칸(r, c)에 적힌 문�
www.acmicpc.net
접근
DFS를 이용하여 문제를 풀었다. 이때 주의할 점은 DFS를 통해 모든 경우의 수를 전부 돌아본다면 미로의 최대 크기가 500x500이므로 시간 초과가 날 것이다. 그렇다면 어떻게 해야 효율적으로 탐색할 수 있을까?
어떤 경로에 대해 탐색이 끝났다면 우리는 그 경로에 대한 답-더이상 나아갈 길이 없거나 미로를 탈출했거나-을 알고 있다. 이때 이 결과를 기억해주는 배열을 만들어주면 다른 좌표에서 출발하여 이미 탐색이 끝난 좌표에 진입하는 순간 우리는 더 가보지 않아도 이 길의 끝에 어떤 답이 있는지 알 수 있을 것이다. 이와 같은 방법을 메모이제이션(memoization)이라고 한다. 우리는 이 메모이제이션 기법을 이용하여 DFS의 탐색 시간을 대폭 단축할 수 있다. 이해가 어렵다면 아래의 사진을 참고하길 바란다.
이렇게 이미 탐색한 경로에 대한 결과를 기억해두면 불필요한 탐색을 줄일 수 있을 것이다.
코드
// algorithm study
// BOJ_17090_미로 탈출하기
#include <iostream>
#include <vector>
using namespace std;
int n, m, visit[510][510] = {0}, dp[510][510] = {0}, answer = 0;
char map[510][510];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
void dfs(int i, int j) {
visit[i][j] = 1;
int rx, ry;
if (map[i][j] == 'D') {
rx = i + dx[0];
ry = j + dy[0];
} else if (map[i][j] == 'U') {
rx = i + dx[1];
ry = j + dy[1];
} else if (map[i][j] == 'R') {
rx = i + dx[2];
ry = j + dy[2];
} else if (map[i][j] == 'L') {
rx = i + dx[3];
ry = j + dy[3];
}
if (visit[rx][ry] == 1) {
dp[i][j] = 2;
}
if (rx < 0 || rx >= n || ry < 0 || ry >= m) {
dp[i][j] = 1;
answer++;
return;
} else if (dp[rx][ry] == 1) {
dp[i][j] = 1;
answer++;
return;
} else if (dp[rx][ry] == 2) {
dp[i][j] = 2;
return;
} else {
dfs(rx, ry);
visit[rx][ry] = 0;
if (dp[rx][ry] == 1)
dp[i][j] = 1;
else if (dp[rx][ry] == 2)
dp[i][j] = 2;
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (dp[i][j] == 2)
continue;
dfs(i, j);
visit[i][j] = 0;
}
}
cout << answer;
return 0;
}
'☽ Algorithm > BOJ' 카테고리의 다른 글
[BOJ 백준] 2916번 자와 각도기 (0) | 2020.05.26 |
---|---|
[BOJ 백준] 10942번 팰린드롬? (0) | 2020.05.25 |
[BOJ 백준] 16954번 움직이는 미로 탈출 (0) | 2020.05.24 |
[BOJ 백준] 1766번 문제집 (0) | 2020.05.22 |
[BOJ 백준] 16939번 2x2x2 큐브 (0) | 2020.05.21 |
Comments