728x90
시간 제한 1초, 메모리 제한 512MB
# 조건
- 크기가 N x M인 미로가 있고, 미로는 크기가 1 x 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개의 줄에는 미로의 각 칸에 적힌 문자가 주어진다.
출력
- 첫째 줄에 탈출 가능한 칸의 수를 출력한다.
# 접근 방법
- bfs나 dfs를 이용하여 풀어줄 수 있다.
- dfs의 경우 아직 방문하지 않았다면 적혀있는 방향대로 탐색하며 탈출 가능한지를 return 해주면 된다.
- 또는, 진행 중에 이미 다른 경로에서 방문한 적 있다면 이 경로가 탈출 가능한지 아닌지 나와있기 때문에 visited 값을 return 해주면 된다.
- bfs의 경우 주어진 배열을 먼저 탐색하며 탈출 가능한 곳을 q에 넣어준다.
- 이후, 역방향으로 탐색해야 하는데 이를 위해서 DRUL 순으로 0 1 2 3으로 변경해주고, 4 방향을 탐색해주면 된다.
- 즉, 현재 위치에서 1칸 위를 탐색한다면 1칸 위는 U를 나타내는 2가 적혀있어야 탈출 가능한 루트가 된다.
- 마찬 가지로 진행 중 탈출 가능한 경로라면 continue 해주면 된다.
dfs 풀이
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
def dfs(ci, cj):
# 범위를 벗어났거나 이미 방문한 경로라면 return
if ci < 0 or ci >= N or cj < 0 or cj >= M:
return 1
if visited[ci][cj]:
return visited[ci][cj]
visited[ci][cj] = 2
visited[ci][cj] = dfs(ci+direct[maze[ci][cj]][0], cj+direct[maze[ci][cj]][1])
return visited[ci][cj]
N, M = map(int, input().split())
maze = [list(input().rstrip()) for _ in range(N)]
direct = {'U' : (-1, 0), 'D': (1, 0), 'R': (0, 1), 'L':(0, -1)}
visited = [[0]*M for _ in range(N)]
for i in range(N):
for j in range(M):
if not visited[i][j]:
dfs(i, j)
result = 0
for i in visited:
result += i.count(1)
print(result)
bfs 풀이
### 위에는 dfs 풀이
### 밑에는 bfs 풀이
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
from collections import deque
N, M = map(int, input().split())
maze = [list(input().rstrip()) for _ in range(N)]
# 역방향 체크 위해서 DRUL 순
# 역방향 계산 편하게 하기위해 DRUL -> 0123 변경해주고 탈출 가능 한 곳 can에 넣기
di, dj = [1, 0, -1, 0], [0, 1, 0, -1]
can = deque()
visited = [[0]*M for _ in range(N)]
result = 0
for i in range(N):
for j in range(M):
if maze[i][j] == 'D':
maze[i][j] = 0
elif maze[i][j] == 'R':
maze[i][j] = 1
elif maze[i][j] == 'U':
maze[i][j] = 2
else:
maze[i][j] = 3
ni, nj = i+di[maze[i][j]], j+dj[maze[i][j]]
if not 0<=ni<N or not 0<=nj<M:
can.append((i, j))
visited[i][j] = 1
result += 1
# 탈출 가능한 곳부터 역방향 탐색
while can:
si, sj = can.popleft()
for d in range(4):
# 역방향이므로 범위를 벗어나면 안됨
# 역방향 체크 위해서는 1칸 위를 쳐다보면 U를 뜻하는 2가 있어야됨
ni, nj = si+di[d], sj+dj[d]
if 0<=ni<N and 0<=nj<M and visited[ni][nj] == 0:
if maze[ni][nj] == (d+2) % 4:
can.append((ni, nj))
visited[ni][nj] = 1
result += 1
print(result)
728x90
'ALGORITHM > DFS, BFS, 그래프 탐색' 카테고리의 다른 글
[백준 16174번] 파이썬 - 점프왕 쩰리(Large) (0) | 2023.08.22 |
---|---|
[백준 21937번] 파이썬 - 작업 (0) | 2023.08.19 |
[백준 18404번] 파이썬 - 현명한 나이트 (0) | 2023.08.17 |
[백준 2636번] 파이썬 - 치즈 (0) | 2023.08.16 |
[백준 11123번] 파이썬 - 양 한마리... 양 두마리... (0) | 2023.08.15 |