Algorithm/백준 BOJ

[백준] [Python] #14503 로봇청소기

은세라 2022. 4. 16. 23:03

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

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어

www.acmicpc.net

가장 기본적인 구현 문제에 해당한다.

1차 시도

시키는 대로 코드로 옮기는게 장땡이란 생각으로 옮긴 코드인데 청소를 하지 못하는 경우를 처리하는게 복잡해졌다.

import sys
sys.stdin = open("input.txt", "r")

n,m = map(int, input().split())
r,c,d = map(int, input().split()) #0북,1동,2남,3서
graph = [[] for _ in range(n)]
for i in range(n):
    graph[i] = list(map(int, input().split()))
dir = [[-1,0],[0,1],[1,0],[0,-1]] #북동남서
cnt = 0

while(True):
    print(r,c,d)
    if graph[r][c] != 1:
        graph[r][c] = 1 #현재 위치를 청소한다
        cnt+=1
    #왼쪽을 확인한다 북->서(0->3), 동->북(1->0), 남->동(2->1), 서->남(3->2)
    if 0<d:
        d_left = d-1 
    else: #d==0
        d_left = 3
    nr = r + dir[d_left][0]
    nc = c + dir[d_left][1]
    d = d_left

    if 0<=nr<n and 0<=nc<m and graph[nr][nc]==0: #왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면
        r = nr
        c = nc #한 칸을 전진            
    else: # 왼쪽 방향에 청소할 공간이 없다면
        flag = False

        for i in range(4): 
            if graph[r+dir[i][0]][c+dir[i][1]] == 0:
                flag = True
        if not flag: #네 방향 모두 청소가 이미 되어있거나 벽인 경우
            if graph[r-dir[d][0]][c-dir[d][1]]==0 and 0<=r-dir[d][0]<n and 0<=c-dir[d][1]<m:
                r -= dir[d][0]
                c -= dir[d][1] #바라보는 방향을 유지한 채로 한 칸 후진
                break
            else: #뒤쪽 방향이 벽이라 후진도 할 수 없는 경우
                print('end>>>>',r,c,d)
                for g in graph:
                    print(g)
                print('ans>>>>', cnt)
                exit(0)

2차 시도

방문 여부를 확인하는 visited를 추가하였더니 코드가 깔끔해졌다.

n,m = map(int, input().split())
r,c,d = map(int, input().split()) #0북,1동,2남,3서
graph = [[] for _ in range(n)]
visited = [[0]*m for _ in range(n)]
for i in range(n):
    graph[i] = list(map(int, input().split()))
dir = [[-1,0],[0,1],[1,0],[0,-1]] #북동남서

visited[r][c] = 1
cnt = 1

while(True):
    flag = False
    for _ in range(4):   
        #왼쪽을 확인한다 북->서(0->3), 동->북(1->0), 남->동(2->1), 서->남(3->2)
        nr = r + dir[(d+3)%4][0]
        nc = c + dir[(d+3)%4][1]
        d = (d+3)%4
        if 0<=nr<n and 0<=nc<m and graph[nr][nc]==0: #왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면
            if visited[nr][nc] == 0:
                visited[nr][nc] = 1 #현재 위치를 청소한다
                cnt+=1
                r = nr
                c = nc #한 칸을 전진  
                flag = True
                break  

    if not flag: #네 방향 모두 청소가 이미 되어있거나 벽인 경우
        if graph[r-dir[d][0]][c-dir[d][1]]==1: #뒤쪽 방향이 벽이라 후진도 할 수 없는 경우
            print(cnt)
            break
        else: 
            r = r- dir[d][0]
            c = c- dir[d][1] #바라보는 방향을 유지한 채로 한 칸 후진