안녕하세요.
브리아나입니다.
오늘은 14503 백준 로봇청소기 문제를 풀어보겠습니다.
BFS(너비우선탐색, breadth-first-search)로 풀어보겠습니다.
문제링크.
https://www.acmicpc.net/problem/14503
14503번: 로봇 청소기
첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$ 둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽
www.acmicpc.net
문제 아이디어 정리하기.
1) 이슈가 될 수 있는 아이디어 정리하기
청소기 방향
cd = 0(북), 1(동), 2(남), 3(서) # cd: current direction
dx = [-1, 0, 1, 2]
dy = [0, 1, 0, -1]
청소기가 왼쪽 방향으로 회전한다.
현재 만약 서쪽이라면, 남->동->북->서 방향으로 회전
(현재 만약 3, 2->1->0->3 으로 회전)
IDEA: 보수를 더해주고 나머지 구하기 => (dr+3)%4
2-> 5%4 -> 1
1 -> 4%4 -> 0
0 -> 3%4 -> 3
3 -> 6%4 -> 2
2) 1번 항목부터 식을 세워보기.
1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
- 지도 = arr / 현재위치 (cx, cy) / 벽(1),청소x(0)이니까 청소하면(2)
- 청소 했는지 체크 count 변수
room_map[cx][cy] = 2
cnt+=1
2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
- 후진: 방향 부호를 반전 시켜주면 됨.
- bx = cx - dx[cd] (back_x = current_x - dx[current_direction]
- if room_map[bx][by] != 1: # 벽 아니면 후진 가능
- cx, cy = bx, by # 업데이트
- 1번으로 돌아가야 하니까 순회(for) 멈추기: break
- while문 빠져나갈 수 있게 (True -> False)
3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
반시계 방향으로 90도 회전한다.
바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
1번으로 돌아간다.
- 왼쪽 방향부터 4방향 탐색 (다음 방향이니까 (nx, ny)) (이때, n은 next를 의미)
- for: 빈곳(0) 있다? 2(청소) / 새로운 방향, 좌표 update
- else: 빈곳(0) 없다? 후진 벽 아니라면? 후진 / 후진 벽이라면 종료
문제풀이.
1. 입력부, 출력부 작성하기
N, M = map(int, input().split())
cx, cy, cd = map(int, input().split())
room_map = [list(map(int, input().split())) for _ in range(N)]
def solution(cx, cy, cd):
print("algorithm here")
print(solve(cx, cy, cd))
2. 전체 알고리즘 넣기
import sys
sys.stdin = open("input_14503.txt", "r")
# 북, 동, 남, 서 (반시계 90' 방향)
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
N, M = map(int, input().split())
cx, cy, cd = map(int, input().split()) # current_x, current_y, current_direction
room_map = [list(map(int, input().split())) for _ in range(N)]
def solution(cx, cy, cd):
clean_count = 0
while True:
# 1) current room / no clean? / then, clean
if room_map[cx][cy] == 0:
room_map[cx][cy] = 2
clean_count += 1
con = True
while con:
for nd in ((cd+3)%4, (cd+2)%4, (cd+1)%4, cd): # condition access OK
nx, ny = cx+dx[nd], cy+dy[nd]
if room_map[nx][ny] == 0:
cx, cy, cd = nx, ny, nd
con = False
break # 청소 당첨되는 즉시 퇴장
else: # no condition
bx, by = cx-dx[cd], cy-dy[cd] # 후진
if room_map[bx][by] != 1:
cx, cy = bx, by
break
else:
return clean_count
print(solution(cx, cy, cd))
궁금한 사항 있으시면 질문 댓글로 주세요 :)
'Python' 카테고리의 다른 글
1182. 부분 수열 백준 문제풀이 python - 백트래킹 (0) | 2024.02.06 |
---|---|
[SWEA] 2072. 홀수만 더하기 (0) | 2024.01.18 |
동영상 파일 변환 - .avi에서 .mp4 변환 방법 / HTML Video player에서 avi는 지원하지 않아 mp4로 python코드로 변환하는 방법 (0) | 2023.10.25 |
Python 특정 확장자 찾는 방법 - glob 사용하기 (0) | 2023.10.16 |
Anaconda 가상 환경 생성 및 가상 환경 제거 방법 (0) | 2023.10.06 |