ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 14503. 로봇 청소기
    Programmers 2024. 4. 21. 19:59
    728x90

    https://www.acmicpc.net/problem/14503

    # output: 청소하는 영역의 개수
    # N * M
    # 동서남북
    # 반시계 방향으로 90도 회전
    
    # dfs
    def dfs(x, y, d):
        global count
        # 방향 : 북 / 동 / 남 / 서
        # direction = [0, 1, 2, 3]
        dx = [-1, 0, 1, 0]
        dy = [0, 1, 0, -1]
        if not visited[x][y]:
            visited[x][y] = 1
            # 아직 청소되지 않은 경우, 현재 칸을 청소한다.
            if graph[x][y] == 0:
                graph[x][y] = 1
                count += 1
    
        aldy_cln = 0
        for i in range(4):
            nx, ny = x + dx[i], y + dy[i]
            if graph[nx][ny] == 1:
                aldy_cln += 1
    
        # 청소되지 않은 빈 칸이 없는 경우
        if aldy_cln == 4:
            # 방향은 유지하되, 후진 가능하면 후진
            j = (d + 2) % 4
            nx, ny = x + dx[j], y + dy[j]
            if (0 <= nx < n) and (0 <= ny < m):
                dfs(nx, ny, d)
            # 후진 할 수 없으면 멈춤
            else:
                return
    
        # 청소되지 않은 빈 칸이 있는 경우
        else:
            # 반시계 방향으로 90도 회전
            d = (d + 3) % 4
            nx, ny = x + dx[d], y + dy[d]
            # 청소 및 방문 처리
    
            if (0 <= nx < n) and (0 <= ny < m) and not graph[nx][ny]:
                visited[nx][ny] = 1
                graph[nx][ny] = 1
                count += 1
                dfs(nx, ny, d)
    
            dfs(x, y, d)
    
    
    
    # main
    n, m = map(int, input().split())
    
    start_x, start_y, d = map(int, input().split())
    
    graph = [list(map(int, input().split())) for _ in range(n)]
    visited = [[0]*m for _ in range(n)]
    
    
    count = 0
    
    dfs(start_x, start_y, d)
    
    print(count)
    # output: 청소하는 영역의 개수
    # N * M
    # 동서남북
    # 반시계 방향으로 90도 회전
    
    # dfs
    def dfs(x, y, d):
        global count
        # 방향 : 북 / 동 / 남 / 서
        # direction = [0, 1, 2, 3]
        if graph[x][y] == 0:
            count += 1
            graph[x][y] =2
    
        for _ in range(4):
            # 90도씩 왼쪽으로 회전하면서 청소할 곳이 있는지 확인
            nd = (d + 3) % 4
            nx, ny = x + dx[nd], y + dy[nd]
            if graph[nx][ny] == 0:
                # 청소
                dfs(nx, ny, nd)
                return
            d = nd
    
        # 청소되지 않은 빈 칸이 없는 경우
        nd = (d + 2) % 4
        nx, ny = x + dx[nd], y + dy[nd]
        # 후진 할 수 없으면 멈춤
        # 테두리는 모두 벽으로 둘러싸여 있으므로, 인덱스가 범위를 벗어날 경우는 고민하지 않아도 됨
        if graph[nx][ny] == 1:
            return
        dfs(nx, ny, d)
    
    # main
    n, m = map(int, input().split())
    
    start_x, start_y, d = map(int, input().split())
    
    graph = [list(map(int, input().split())) for _ in range(n)]
    
    dx = [-1, 0, 1, 0]
    dy = [0, 1, 0, -1]
    
    count = 0
    
    dfs(start_x, start_y, d)
    
    print(count)

    1. 벽을 1로 둔다는 사실을 간과하고 0, 1로만 접근하려고 했고

    2. 내가 이해했을 때는 청소기가 있는 위치에서 네 방면을 모두 확인한 후에 청소할 곳이 있다면 그제서야 90도 반시계 방향 회전을 하는 것으로 이해를 했는데, 생각해보니 말이 안되는 발상이긴 했다.

    확인을 위해서는 반드시 회전을 거쳐야 할 것이고, 상식적으로 회전을 하는 도중에 청소가 되지 않은 부분을 확인하면 청소가 되는 것이 맞을 것이다.

    코드 내 구현하는 방법은 비슷했으나, 문제를 잘못 이해했던 점이 아쉽다.

    모든 정확한 답안은 문제를 정확하게 읽고 이해하는 데서 비롯된다는 점을 상기하자.

    문제를 제대로 이해하지 않는다면 그 어떤 정답도 도출해낼 수 없다.

    728x90

    'Programmers' 카테고리의 다른 글

    1039.교환  (0) 2024.05.19
    9205.맥주 마시면서 걸어가기  (0) 2024.04.20
    2468. 안전영역  (0) 2024.04.18
    [2644]촌수 계산  (0) 2024.04.10
    [SQL] 노선별 평균 역 사이 거리 조회하기  (0) 2024.03.10
Designed by Tistory.