구현 - 로봇 청소기

jisu_log·2025년 4월 6일

알고리즘 문제풀이

목록 보기
15/105

n, m = map(int, input().split())
line = list(map(int, input().split()))
r = line[0]
c = line[1]
d = line[2]

maps = []
# maps의 값 -> 0: 청소해야하는 곳, 1: 벽, 2: 청소완료

for i in range(0, n):
    line = list(map(int, input().split()))
    maps.append(line)


cnt = 0  # 청소한 영역 수


def turn(d):
    if d == 0:  # 북쪽에서
        d = 3  # 서쪽으로 턴
    elif d == 1:  # 동쪽에서
        d = 0  # 북쪽으로 턴
    elif d == 2:  # 남쪽에서
        d = 1  # 동쪽으로 턴
    else:  # 서쪽에서
        d = 2  # 남쪽으로 턴

    return d


def get_front(d, r, c):
    if d == 0:  # 북쪽을 향한다면
        r = r - 1
    elif d == 1:  # 동쪽
        c = c + 1
    elif d == 2:  # 남쪽
        r = r + 1
    else:  # 서쪽
        c = c - 1

    return r, c  # 현재 방향의 앞쪽 좌표 리턴


def get_back(d, r, c):
    if d == 0:  # 북쪽을 향한다면
        r = r + 1
    elif d == 1:  # 동쪽
        c = c - 1
    elif d == 2:  # 남쪽
        r = r - 1
    else:  # 서쪽
        c = c + 1

    return r, c  # 현재 방향의 뒷쪽 좌표 리턴


# ------- 청소 시작
while True:
    # 작동 가이드 1번 문항: 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소
    if maps[r][c] == 0:
        maps[r][c] = 2
        cnt += 1
    # 작동 가이드 3번 문항: 주변 4칸 중 청소되지 않은 빈칸이 있는 경우
    if (
        (r + 1 < n and maps[r + 1][c] == 0)
        or (r - 1 >= 0 and maps[r - 1][c] == 0)
        or (c + 1 < m and maps[r][c + 1] == 0)
        or (c - 1 >= 0 and maps[r][c - 1] == 0)
    ):

        # 반시계방향 90도 회전
        d = turn(d)
        # 현재 방향의 앞쪽 칸의 좌표 계산
        r_f, c_f = get_front(d, r, c)
        # 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진
        if 0 <= r_f < n and 0 <= c_f < m and maps[r_f][c_f] == 0:
            r = r_f
            c = c_f
            continue
    # 작동 가이드 2번 문항: 현재 칸의 주변 칸 중 청소되지 않은 빈 칸이 없는 경우
    else:
        # 현재 방향의 뒷쪽 칸의 좌표 계산
        r_b, c_b = get_back(d, r, c)
        # 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다
        if 0 <= r_b < n and 0 <= c_b < m and maps[r_b][c_b] != 1:
            r = r_b
            c = c_b
            continue
        # 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다
        else:
            break

# ------ 청소 종료

# 작동을 시작한 후 작동을 멈출 때까지 청소하는 칸의 개수를 출력
print(cnt)

0개의 댓글