Algorithm/acmicpc.net

빡구현은 체력전이다. (#14503 로봇청소기)

winney916 2024. 3. 21. 00:48
728x90

#14503 로봇청소기 https://www.acmicpc.net/problem/14503

 

14503번: 로봇 청소기

첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽

www.acmicpc.net

 

고민도 필요없었다.

 

문제의 설명을 그대로 코드로 옮겼다. (말 그대로 구현)

 

# 1. get input
h, w = map(int, input().split())  # map size width - height

x, y, d = map(int, input().split())  # start position, x, y, direction

# 2. make map with input
maps = [list(map(int, input().split())) for _ in range(h)]

# 3. 탐색 로직 구현 - dfs? 단순 반복문으로 될거같다.

# 이동하기 = [북, 동, 남, 서] <- d는 0, 1, 2, 3으로 대응한다.
moves = [[-1, 0], [0, 1], [1, 0], [0, -1]]

# 청소된 칸 저장하기
cleaned_map = [[0 for _ in range(w)] for __ in range(h)]


def valid_pos(x, y):
    global h, w
    return ((0 <= x < h) and (0 <= y < w)) and (not maps[x][y])


while True:  # 아직 종료 조건은 확실치 않다. break로 끝내야할까?

    ## 1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
    if cleaned_map[x][y] == 0:
        cleaned_map[x][y] = 1

    ## 2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
    num_valid_way = sum(
        [
            valid_pos(x + mx, y + my) and not cleaned_map[x + mx][y + my]
            for mx, my in moves
        ]
    )
    # print("valid_way : ", num_valid_way)
    if num_valid_way == 0:
        ### 2-1. 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
        back_direct = (d + 2) % 4
        # print("back_direction : ", back_direct)
        mx, my = moves[back_direct]
        if valid_pos(x + mx, y + my):
            x, y = x + mx, y + my
            # d = back_direct
        ### 2-2. 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
        else:
            break
    ## 3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우
    else:
        ### 3-1. 반시계방향으로 90도 회전한다.
        d = 3 if d == 0 else d - 1
        # print("direction : ", d)
        ### 3-2. 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
        mx, my = moves[d]
        if valid_pos(x + mx, y + my) and not cleaned_map[x + mx][y + my]:
            x, y = x + mx, y + my
            # print(x, y)
        ### 3-3. 1번으로 돌아간다.


answer = sum([sum(r) for r in cleaned_map])
print(answer)

 

방향값, 이동, 벽과 청소해야되는 곳의 정보가 있는 맵, 청소한 정보가 있는 맵 등을 어떻게 구현할 것인지 머리를 잘 써야한다.

 

약간 아쉬운 점은 마음이 급해서 그랬는지 맵을 두 개로 만들었다.

 

다시 만든다면 청소 여부를 판단하는 값을 2로 두어 하나의 맵 데이터에서 진행했을 것 같다.