문제
크기가 N×M인 미로가 있고, 미로는 크기가 1×1인 칸으로 나누어져 있다. 미로의 각 칸에는 문자가 하나 적혀있는데, 적혀있는 문자에 따라서 다른 칸으로 이동할 수 있다.
어떤 칸(r, c)에 적힌 문자가
- U인 경우에는 (r-1, c)로 이동해야 한다.
- R인 경우에는 (r, c+1)로 이동해야 한다.
- D인 경우에는 (r+1, c)로 이동해야 한다.
- L인 경우에는 (r, c-1)로 이동해야 한다.
미로에서 탈출 가능한 칸의 수를 계산해보자. 탈출 가능한 칸이란, 그 칸에서 이동을 시작해서 칸에 적힌대로 이동했을 때, 미로의 경계 밖으로 이동하게 되는 칸을 의미한다.
입력
첫째 줄에 미로의 크기 N, M(3 ≤ N, M ≤ 500)이 주어진다. 둘째 줄부터 N개의 줄에는 미로의 각 칸에 적힌 문자가 주어진다.
출력
첫째 줄에 탈출 가능한 칸의 수를 출력한다.
어떤 칸에서 이동할 수 있는 방향은 정해져있습니다.
따라서 어떤 정점 에서 출발해서 경계 밖으로 나갈 수 있는지 dfs로 확인 할 때,
경계 밖으로 나갈 수 있는 경로라면 그 경로상 정점에 모두 1을 저장합니다.
만약 불가능하다면 모두 0을 저장합니다.
이후 방문하지 않은 정점들에대해 똑같이 dfs를 수행하는데, 만약 이미 방문했던 정점이라면
그 정점에 저장된 데이터가 있다면 그 데이터를 반환합니다.
dp입니다.
#include<bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(false),cin.tie(NULL);
#define mset(v) memset(v,0,sizeof(v));
#define rep(i,a) for(int i=0;i<a;++i)
#define REP(i,a) for(int i=1;i<=a;++i)
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef tuple<int, int, int>ti;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
int dy[] = { -1,0,1,0 }, dx[] = { 0,1,0,-1 }, INF = 987654321;
int dp[501][501], N, M, cnt;
char mp[501][501];
int dfs(int y, int x) {
if (dp[y][x]!=-1)return dp[y][x];
dp[y][x] = 0;
if (mp[y][x] == 'U') {
if (y == 1)return dp[y][x] = 1;
return dp[y][x] = dfs(y - 1, x);
}
else if (mp[y][x] == 'D') {
if (y == N)return dp[y][x] = 1;
return dp[y][x] = dfs(y + 1, x);
}
else if (mp[y][x] == 'R') {
if (x == M)return dp[y][x] = 1;
return dp[y][x] = dfs(y, x + 1);
}
else if (mp[y][x] == 'L') {
if (x == 1)return dp[y][x] = 1;
return dp[y][x] = dfs(y, x - 1);
}
}
int main() {
FAST;
memset(dp, -1, sizeof(dp));
cin >> N >> M;
REP(i, N) {
REP(j, M) {
cin >> mp[i][j];
}
}
REP(i, N)REP(j, M) {
if (dp[i][j] == -1)dfs(i, j);
}
REP(i, N)REP(j, M)if (dp[i][j] == 1)cnt++;
cout << cnt;
}
'baekjoon' 카테고리의 다른 글
[백준] 2225 합분해 (0) | 2023.07.05 |
---|---|
[백준] K번째 수 (복습 필요,,) (0) | 2023.07.05 |
[백준] 3067 Coins (0) | 2023.07.04 |
[백준] 6672 Electricity (0) | 2023.07.04 |
[백준] 10891 Cactus? Not cactus? -선인장그래프 (0) | 2023.07.03 |