https://www.acmicpc.net/problem/14503
문제
풀이
# 방의 크기
n,m = map(int,input().split())
# 로봇 청소기가 있는 방의 좌표(r,c)와 로봇청소기가 바라보는 방향(d)
r,c,d = map(int,input().split())
# d = 0 (북), 1(동), 2(남), 3(서)
room = []
for i in range(n):
room_num = list(map(int,input().split()))
room.append(room_num)
# 4방향을 체크한다. (청소할 구역이 있는지 없는지)
def check4can(r,c,room):
cnt = 0
# 먼저 r,c가 최상단 (0,0), 최하단 (n-1,m-1)에 있을 때를 배제
if r == 0 and c == 0:
if room[r+1][c] == 0 or room[r][c+1] == 0:
cnt += 1
elif r == n-1 and c == m-1:
if room[r-1][c] == 0 or room[r][c-1] == 0:
cnt += 1
# 이후 r,c가 단독으로 최상단 혹은 최하단에 존재할 경우를 나눠줌
else:
if r == 0:
if room[r+1][c] == 0 or room[r][c-1] == 0 or room[r][c+1] == 0:
cnt += 1
elif c == 0:
if room[r+1][c] == 0 or room[r-1][c] == 0 or room[r][c+1] == 0:
cnt += 1
elif r == n-1:
if room[r-1][c] == 0 or room[r][c-1] == 0 or room[r][c+1] == 0:
cnt += 1
elif c == m-1:
if room[r+1][c] == 0 or room[r-1][c] == 0 or room[r][c-1] == 0:
cnt += 1
else:
if room[r-1][c] == 0 or room[r][c-1] == 0 or room[r+1][c] == 0 or room[r][c+1] == 0:
cnt += 1
# 만약 청소할 구역이 남았다면 False, 없다면 True를 보낸다.
if cnt == 0:
return True
else:
return False
answer = 0
while True:
# 문제에서 1번에 해당 청소되지 않았으면 현재 칸을 청소, 그리고 2로 바꿔준다. (2는 청소를 했다는 표시)
# 청소를 했다면 후진을 할 수 있지만 3번에서 이동이 안된다.
if room[r][c] == 0:
answer += 1
room[r][c] = 2
# 만약 4방향 모두 청소할 곳이 없다면
if check4can(r,c,room):
# 만약 방향이 북쪽이면 후진하면 남쪽 그러면 r == n-1이 아니라면 후진 가능 r을 +1 해준다.
if d == 0:
if r != n-1 and room[r+1][c] != 1:
r = r+1
else:
break
# 만약 방향이 동쪽이면 후진하면 서쪽 그러면 c == 0이 아니라면 후진 가능 c을 -1 해준다.
elif d == 1:
if c != 0 and room[r][c-1] != 1:
c = c-1
else:
break
# 만약 방향이 남쪽이면 후진하면 북쪽 그러면 r == 0이 아니라면 후진 가능 r을 -1 해준다.
elif d == 2:
if r != 0 and room[r-1][c] != 1:
r = r-1
else:
break
# 만약 방향이 서쪽이면 후진하면 동쪽 그러면 c == m-1이 아니라면 후진 가능 c를 +1 해준다.
else:
if c != m-1 and room[r][c+1] != 1:
c = c+1
else:
break
# 만약 4방향 중 청소할 곳이 있다면
else:
# 4방향 중 청소할 곳을 찾는다.
# 무조건 현재 방향에서 90도로 돌려야하므로 90도를 반복해서 돌리면서 0인 곳을 찾음
while True:
# 현재 방향에서 90도를 돌려주고
if d == 0:
d = 3
# 만약 칸의 끝지점이 아니고 1(벽) 2(이미 청소한 구역)이 아니라면 전진한다.
if c != 0 and room[r][c-1] == 0:
c = c - 1
break
elif d == 1:
d = 0
if r != 0 and room[r-1][c] == 0:
r = r - 1
break
elif d == 2:
d = 1
if c != m and room[r][c + 1] == 0:
c = c + 1
break
else:
d = 2
if r != n and room[r + 1][c] == 0:
r = r + 1
break
# 정답을 출력
print(answer)
구현으로 풀이하였다.
느낀점
문제 자체 이해가 조금 힘들어서 헷갈린 부분이 좀 있었다.
먼저 1은 청소가 끝난 구역이 아니라 "벽"이다.
처음에 벽을 가장자리 부분으로 착각했는데 숫자 1자체가 벽이였다.
그리고 후진은 청소를 진행했던 (방문한) 구역이여도 후진이 가능하지만 전진(청소할 구역이 남아있는 경우)은 이미 청소한 구역일 경우 전진할 수 없다. (벽은 당연히 안된다) 즉, 벽이 아닌 청소를 해야하는 구역으로만 전진이 가능하다.
마지막에 저 부분이 헷갈렸다. 그래서 후진은 1만 아니면 후진을 하지만 전진은 0이여야 전진할 수 있음
'알고리즘 > 백준' 카테고리의 다른 글
백준 11478 - 서로 다른 부분 문자열의 개수 (0) | 2024.06.09 |
---|---|
백준 2003 - 수들의 합 2 (0) | 2024.06.07 |
백준 1748 - 수 이어 쓰기 1 (0) | 2024.06.06 |
백준 1003 - 피보나치 함수 (0) | 2024.06.05 |
백준 2579 - 계단 오르기 (0) | 2024.06.04 |