[백준] 14503번: 로봇 청소기 - python
문제보기
https://www.acmicpc.net/problem/14503
14503번: 로봇 청소기
로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어
www.acmicpc.net
풀이 & 코드
해당 문제는 새로운 알고리즘 보다는 문제가 말하는 대로 코드를 작성할 수 있는 가를 판단하는 문제이다. solved.ac 에서는 gold5 정도에 랭크되어 있다.
먼저 데이터 전처리 부분이다. direction이라는 변수명으로 2차원 배열에서의 상하좌우를 저장했고 해당 칸을 청소했는 지 여부를 판단하기 위해 방 크기와 동일하게 check라는 0으로 만들어진 2차원 배열을 선언해 주었다.
n, m = map(int, input().split())
r, c, d = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(n)]
direction = [[-1,0],[0,1],[1,0],[0,-1]]
check = [[0 for _ in range(m)] for _ in range(n)]
알고리즘 부분은 문제에서 말하는 대로 그대로 작성했다.
1번
1번의 내용대로 while문을 통해 현재위치가 바뀔때마다 현재 위치를 청소하도록 구현하였다. 단, 그 위치의 청소여부를 보고 시행했다. 그 이유는 2-3을 보면 청소여부를 확인하지 않고 후진으로 이동하는 경우가 있다. 이 경우에 청소가 되어 있는 지 확인해야하기 때문에 추가해 주었다. 또한 시간 절약을 위해 청소한 칸의 개수를 answer이라는 변수에 저장했다.
while True:
if check[r][c] == 0:
check[r][c] =1
answer += 1
2-1, 2-2번
for _ in range(4):
d = (d - 1) % 4
nr = r + direction[d][0]
nc = c + direction[d][1]
if check[nr][nc] == 0 and board[nr][nc] == 0:
r = nr
c = nc
break
먼저 d에 1을 빼 왼쪽 방향을 구현하였고 만일 그 방향으로 전진한 [nr][nc]가 청소가 되어있지 않고 벽도 아니라면 이동하도록 코드를 작성하였다. 상하좌우 즉 4번동안 이동을 하지 못하는 경우(2-3, 2-4)를 for-else구문을 통해 구현했다.
2-3, 2-4
else:
back = (d+2)%4
r += direction[back][0]
c += direction[back][1]
if board[r][c] == 1:
print(answer)
break
2-3 내용대로 d+2로 반대방향을 구현하였고, 해당 방향으로 이동하였다. 하지만 그 장소가 벽일때 (2-4) 로봇이 동작을 멈추도록 break를 걸어 while문을 종료함과 동시에 지금까지 청소한 개수인 answe을 출력하도록 구현하였다.
전체코드
n, m = map(int, input().split())
r, c, d = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(n)]
direction = [[-1,0],[0,1],[1,0],[0,-1]]
check = [[0 for _ in range(m)] for _ in range(n)]
answer = 0
while True:
if check[r][c] == 0:
check[r][c] =1
answer += 1
for _ in range(4):
d = (d - 1) % 4
nr = r + direction[d][0]
nc = c + direction[d][1]
if check[nr][nc] == 0 and board[nr][nc] == 0:
r = nr
c = nc
break
else:
back = (d+2)%4
r += direction[back][0]
c += direction[back][1]
if board[r][c] == 1:
print(answer)
break