백준 14503 - 로봇 청소기

태태·2023년 5월 18일
0

문제

알고리즘 분류)

  • 구현
  • 시뮬레이션

풀이

시뮬레이션 문제로 각각의 명령에 따라 어떻게 오류없이 구현해내는지가 중요하다
간결한 숏코딩이나 문맥성이 있다면 좋은 코드일 것 같다

각 명령에 의해 코드를 구현한 방법을 정리하자면 이렇다

  1. 현재 위치를 청소한다 -> 로봇이 서있는 곳 좌표 array[r][c]를 'X'로 표시한다
  2. 현재 위치에서 현재 방향을 기준으로 왼쪽 방향부터 차례대로 인접한 칸을 탐색한다. -> 바라보는 방향을 0~3정수로 표현
    a. 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다 -> 바라보는 방향에 따라 왼쪽배열이 0 이면 turn() , move()함수 실행
    b. 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다
    -> 왼쪽배열이 0이 아니면 turn() 함수만 실행
    c. 네 방향 모두 청소가 이미 되어 있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다 -> turn()을 할때마다 cnt가 증가, cnt가 4일시 back()함수 실행
    d. 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다. -> cnt가 4이면서, 뒤쪽배열이 1 일시 반복문 종료

d 딕셔너리)

d = {0:[-1,0],3:[0,-1],2:[1,0],1:[0,1]}

key : 바라보는방향, value : 이동할 인덱스 를 저장한 딕셔너리

turn함수)

def turn(): #왼쪽으로 방향전환
    global look,cnt
    if look==0:
        look=3
    elif look==3:
        look=2
    elif look==2:
        look=1
    elif look==1:
        look=0
    cnt += 1

move함수)

def move(): #보고있는 방향으로 이동
    global r,c,look
    r,c = r+d[look][0] , c+d[look][1]

back함수)

def back(): #보고있는 방향 뒤로 이동
    global r,c,look
    r,c = r-d[look][0] , c-d[look][1]

소스코드

python)

import sys
global r,c,look,cnt
def move(): #보고있는 방향으로 이동
    global r,c,look
    r,c = r+d[look][0] , c+d[look][1]
def back(): #보고있는 방향 뒤로 이동
    global r,c,look
    r,c = r-d[look][0] , c-d[look][1]
def turn(): #왼쪽으로 방향전환
    global look,cnt
    if look==0:
        look=3
    elif look==3:
        look=2
    elif look==2:
        look=1
    elif look==1:
        look=0
    cnt += 1
    
N,M = map(int,input().split())
r,c,look = map(int,input().split())
array = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
d = {0:[-1,0],3:[0,-1],2:[1,0],1:[0,1]}
cnt=0
while True:
    array[r][c] = 'X' #청소한곳 표시
    if cnt==4: #4번 회전했다면
        if array[r-d[look][0]][c-d[look][1]]==1: #뒤쪽이 벽이면
            break
        back() #뒤로이동한다
        cnt=0  #회전초기화
    if look==0: #북쪽을 보고있을 시
        if array[r][c-1] == 0:
            turn()
            move()
            cnt=0
            continue
        else:
            turn()
            continue
    elif look==3: #서쪽을 보고있을 시
        if array[r+1][c] == 0:
            turn()
            move()
            cnt=0
            continue
        else:
            turn()
            continue
    elif look==2: #남쪽을 보고있을 시
        if array[r][c+1] == 0:
            turn()
            move()
            cnt=0
            continue
        else: 
            turn()
            continue
    elif look==1: #동쪽을 보고있을 시
        if array[r-1][c] == 0:
            turn()
            move()
            cnt=0
            continue
        else:
            turn()
            continue
#청소된곳 개수 세기
total=0
for i in range(N):
    for j in range(M):
        if array[i][j] == 'X':
            total+=1
print(total)

너무 길다 ..

profile
과정에서 재미를 느끼지 않는데 성공하는 일은 거의 없다

0개의 댓글