백준 로봇 청소기 코드 및 해설 (파이썬)

2021. 10. 11. 12:05algorithm

반응형

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

 

14503번: 로봇 청소기

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

www.acmicpc.net

 

왼쪽으로 회전 또는 후진하기 위해 현재 방향을 key, 회전 또는 후진을 위한 이동 방향을 value로 갖는 딕셔너리를 정의한다. move_dict는 각 방향을 key로, 그 방향으로 이동하기 위한 (dx, dy)를 value로 갖는다. 

이후 문제의 조건에 맞게 다음을 반복한다. 왼쪽 방향이 벽도 아니고 아직 청소하지 않은 곳이면 왼쪽으로 회전하고, 그 칸으로 이동해 그 칸을 청소한다(2a). 그 외에는 원래 방향으로 돌아올 때까지 왼쪽으로 계속 돈다(2b). 다 돌았는데 청소하러 갈 수 있는 칸이 없으면 현재 방향의 뒤칸이 벽이 아닌지 확인한다. 벽이 아니면 현재 방향 그대로 후진한다(2c). 벽이면 청소를 끝마치고 while문을 빠져나온다(2d). 

마지막으로 청소한 칸의 수인 answer를 출력한다. 

 

import sys

N, M = map(int, sys.stdin.readline().split())
x,y, direction = map(int, sys.stdin.readline().split())

graph = []
for _ in range(N):
	graph.append(list(map(int, sys.stdin.readline().split())))
visited = [[False]*M for _ in range(N)]

# 방향 전환
left_dict = {0:3, 1:0, 2:1, 3:2} # 왼쪽 회전 
rear_dict = {0:2, 1:3, 2:0, 3:1} # 후진 
move_dict = {0:(-1,0), 1:(0,1), 2:(1,0), 3:(0,-1)}

answer = 1
left_rotation = 0

while True:
	visited[x][y] = True
	dx, dy = move_dict[left_dict[direction]]
	# 2a: 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
	if graph[x+dx][y+dy] == 0 and not visited[x+dx][y+dy]:
		x += dx
		y += dy
		direction = left_dict[direction]
		left_rotation = 0
		answer += 1
	else:
		# 2b: 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
		if left_rotation < 4:
			direction = left_dict[direction]
			left_rotation += 1
			continue
		else:
			dx, dy = move_dict[rear_dict[direction]]
			# 2c: 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
			if graph[x+dx][y+dy] == 0:
				x += dx
				y += dy
				left_rotation = 0
				continue
			# 2d: 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
			else:
				break

print(answer)
반응형