문제

[백준] 로봇 청소기 (Gold 5)

요약

  1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
  2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
    1. 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
    2. 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
  3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
    1. 반시계 방향으로 90^\circ 회전한다.
    2. 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
    3. 1번으로 돌아간다.

분류

  • 구현
  • 시뮬레이션
  • dxdy

풀이

1. dxdy

  • 기본적으로 이 문제는 격자를 탐색하는 문제이다.
  • 특이사항으로는, 테두리가 1임이 보장되기 때문에, 격자를 탐색할 때, 탐색할 좌표가 격자 내의 좌표인지 확인해주는 과정이 필요없다는 점이다.
  • 차근차근 dxdy로 조건들을 잘 따지며 풀어주자.


n, m = map(int, input().split())
r, c, d = map(int, input().split())
arr = [
    list(map(int, input().split())) for _ in range(n)
]

dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]


def check_around(cur_r, cur_c, arr):
    for i in range(4):
        ny, nx = cur_r + dy[i], cur_c + dx[i]
        if arr[ny][nx] == 0:
            return True
    return False


cur_r = r
cur_c = c
cur_d = d

cnt = 0

while True:
    # 1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
    if arr[cur_r][cur_c] == 0:
        arr[cur_r][cur_c] = -1
        cnt += 1

    #3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
    if check_around(cur_r, cur_c, arr):

        # 3.1 반시계 방향으로 90^\circ 회전한다.
        cur_d = (cur_d + 3) % 4
        ny, nx = cur_r + dy[cur_d], cur_c + dx[cur_d]

        # 3.2 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
        if arr[ny][nx] == 0:
            cur_r, cur_c = ny, nx

    # 2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
    else:
        back = (cur_d + 2) % 4
        ny, nx = cur_r + dy[back], cur_c + dx[back]

        # 2.1 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
        if arr[ny][nx] != 1:
            cur_r, cur_c = ny, nx

        # 2.2 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
        else:
            break

print(cnt)