https://www.acmicpc.net/problem/14503
💡문제 분석 요약
- 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
- 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
- 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
- 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
- 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
- 반시계 방향으로 90도 회전한다.
- 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
- 1번으로 돌아간다.
💡알고리즘 설계
1. while True로, 더 이동할 공간이 없을 때 까지 반복한다.
2. 현재 칸이 0 인 경우, -1로 바꾼다.
3. 주변의 4 칸을 반시계 방향으로 하나씩 확인하며, 0이 있는 경우 그 칸으로 이동하고 -1로 바꾼다.
4. 주변에 0인 칸이 없다면, 후진한다. 만약 뒤가 1로 벽이라면 break 한다.
💡코드
import sys
input = sys.stdin.readline
N, M=map(int, input().split())
y, x, d=map(int, input().split())
ground=[]
for _ in range(N):
ground.append(list(map(int, input().split())))
dx, dy = [0, 1, 0, -1], [-1, 0, 1, 0]
#d가 0일 경우 북쪽, 1일 경우 동쪽, 2인 경우 남쪽, 3인 경우 서쪽
count=0
while True:
if ground[y][x]==0:
ground[y][x]=-1
count+=1
#청소 되지 않은 빈 칸이 있는 경우
for _ in range(4):
d=(d-1)%4
ny=y+dy[d]
nx=x+dx[d]
if ground[ny][nx]==0:
y=ny
x=nx
break
#청소 되지 않은 빈 칸이 없는 경우
else:
y-=dy[d]
x-=dx[d]
if ground[y][x]!=1:
continue
else:
break
print(count)
💡 느낀점 or 기억할 정보
처음엔 dx dy를 늘 하던대로 동 서 남 북 으로 만들었는데, d가 0이면 북쪽, 1이면 동쪽, 2면 남쪽, 3이면 서쪽으로 시계 방향이었다. 또한 로봇 청소기가 반시계 방향으로 회전하므로, d=(d+1)%4가 아니라 d=(d-1)%4로 해야한다. 문제를 자세히 읽는 것이 중요한 것 같다.
또한 처음에는 로봇 청소기의 위치가 배열의 범위를 벗어나지 않게 제약조건을 줬는데, 입력으로 들어오는 배열은 다 사방이 벽으로 막혀있으므로 굳이 처리할 필요가 없었다.
for문 뒤에 else:를 붙이면 for문이 끝까지 실행된 후에만 else문이 실행된다. (for문 내에서 break로 중지시키면 실행되지 않음)
'알고리즘 문제 풀이' 카테고리의 다른 글
[백준 11889번] 컴백홈 - 파이썬 (0) | 2024.05.11 |
---|---|
[백준 1783번] 병든 나이트 - 파이썬 (0) | 2024.05.11 |
[백준 14889번] 스타트와 링크 - 파이썬 (0) | 2024.05.04 |
[백준 2910번] 빈도 정렬 - 파이썬 (0) | 2024.04.13 |
[백준 9017번] 크로스 컨트리 - 파이썬 (0) | 2024.04.13 |