[백준/Python] 14503번 로봇청소기
문제 설명
로봇 청소기와 방의 상태가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오.
로봇 청소기가 있는 방은 N*M 크기의 직사각형으로 나타낼 수 있으며, 1×1 크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북 중 하나이다. 방의 각 칸은 좌표 (r, c)로 나타낼 수 있고, 가장 북쪽 줄의 가장 서쪽 칸의 좌표가 (0,0), 가장 남쪽 줄의 가장 동쪽 칸의 좌표가 (N-1, M-1)이다.
즉, 좌표 (r, c)는 북쪽에서 (r+1)번째에 있는 줄의 서쪽에서 (c+1)번째 칸을 가리킨다. 처음에 빈 칸은 전부 청소되지 않은 상태이다.
로봇 청소기는 다음과 같이 작동한다.
현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
반시계 방향으로 90도 회전한다.
바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
1번으로 돌아간다.
입력
첫째 줄에 방의 크기 N과 M이 입력된다. 둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 (r, c)와 처음에 로봇 청소기가 바라보는 방향 d가 입력된다. d가 0인 경우 북쪽, 1인 경우 동쪽, 2인 경우 남쪽, 3인 경우 서쪽을 바라보고 있는 것이다.
셋째 줄부터 N개의 줄에 각 장소의 상태를 나타내는 N * M개의 값이 한 줄에 M개씩 입력된다. i번째 줄의 j번째 값은 칸 (i, j)의 상태를 나타내며, 이 값이 0인 경우 (i, j)가 청소되지 않은 빈 칸이고, 1인 경우 (i, j)에 벽이 있는 것이다. 방의 가장 북쪽, 가장 남쪽, 가장 서쪽, 가장 동쪽 줄 중 하나 이상에 위치한 모든 칸에는 벽이 있다. 로봇 청소기가 있는 칸은 항상 빈 칸이다.
출력
로봇 청소기가 작동을 시작한 후 작동을 멈출 때까지 청소하는 칸의 개수를 출력한다.
풀이 과정 1차 시도 : 실패
로봇 청소기가 있는 칸은 무조건 빈칸이고, 청소해야됨. 로봇이 청소한 칸은 2로 업데이트하고 count는 1부터 시작한다.
현재 로봇이 있는 칸의 상, 하, 좌, 우에서 빈 칸이 있으면 청소하고, 없으면 후진 또는 작동을 멈춘다.
왼쪽으로 90도 방향을 바꾸기 위해 turn_left 함수를 만들고, 회전 후에는 로봇 청소기의 위치에 방향을 저장한다. 만약 0이면 카운트를 올리기 위해 clean_room을 재귀로 처리한다. 그리고 청소한 칸을 cnt를 반환한다.
후진할 경우 해당 칸이 벽이라면 cnt를 반환하여 작동을 멈춘다. 벽이 아닌 경우는 cnt에 후진한 경우도 청소할 수 있으므로 재귀호출한다.
=> 여기서 테스트 케이스 1번은 통과하는데 2번은 57이 아니라 68이 나온다. 그러면 청소를 잘 해놓고도 청소하지 않아야 할 부분까지 청소했다는 건데, 어디서 cnt를 더 세는거지? 하고 디버깅을 해봤다.
=> 생각해보니 두 번째 조건문에 들어가는 경우는 0이 아닌 경우 밖에 없다. 즉, 청소할 빈 칸이 없는데 로봇 청소기를 else문에서 돌렸다.
=> 후진하는 경우를 왜 카운트한 건지는 모르지만 여튼 저런 실수를 했다.
풀이 과정 2차 시도 : 성공
위 코드에서 달라진 점은 28번째 코드에서 cnt를 증가시키지 않음!!
사진 출처 : Unsplash의 YoonJae Baik