확실히 시뮬레이션 문제를 풀 때에는,
여러 조건들을 함수화하여 체크하는 것이 좋은 것 같다.
# n, m 입력
n, m = map(int, input().split())
# r, c, d입력
r, c ,d = map(int, input().split())
# room 입력
room = [
list(map(int, input().split()))
for _ in range(n)
]
# 함수들
# all_cleaned_or_wall(x, y):
def all_cleaned_or_wall(x, y):
dxs, dys = [-1, 1, 0, 0], [0, 0, 1, -1]
for dx, dy in zip(dxs, dys):
# 주변 위치
nx, ny = x + dx, y + dy
# 청소안되어있는 빈칸이 나오면,
if not room[nx][ny] and not cleaned_area[nx][ny]:
# 실패
return False
# 다 돌았는데 그런 칸이 안나오면 성공
return True
# back_is_wall(x, y, dir)
def back_is_wall(x, y, dir):
# dxs dys 북 동 남 서 순
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]
# 뒷 방향
back_dir = (dir + 2) % 4
# 뒷 좌표
bx, by = x + dxs[back_dir], y + dys[back_dir]
# 뒷 좌표가 벽이면,
if room[bx][by]:
# 성공
return True
# 아니면 실패
return False
# step_back(x, y, dir)
def step_back(x, y, dir):
# 전역 변수 선언
global r, c
# dxs dys 북 동 남 서 순
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]
# 뒷 방향
back_dir = (dir + 2) % 4
# 뒷 좌표
bx, by = x + dxs[back_dir], y + dys[back_dir]
# 좌표 바꿔주기
r, c = bx, by
# left_is_wall(x, y, dir)
def left_is_wall(x, y, dir):
# dxs dys 북 동 남 서 순
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]
# 왼쪽 방향
left_dir = (dir - 1 + 4) % 4
# 왼쪽 좌표
ls, ly = x + dxs[left_dir], y + dys[left_dir]
# 왼쪽 칸이 벽이면,
if room[ls][ly]:
# 성공
return True
# 아니면 실패
return False
# left_is_dirty(x, y, dir)
def left_is_dirty(x, y, dir):
# dxs dys 북 동 남 서 순
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]
# 왼쪽 방향
left_dir = (dir - 1 + 4) % 4
# 왼쪽 좌표
ls, ly = x + dxs[left_dir], y + dys[left_dir]
# 왼쪽 칸이 청소 안됐으면
if not cleaned_area[ls][ly]:
# 성공
return True
# 아니면 실패
return False
# turn_left(dir)
def turn_left(dir):
# 전역 변수 선언
global d
# dxs dys 북 동 남 서 순
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]
# 왼쪽 방향
left_dir = (dir - 1 + 4) % 4
# 방향 바꿔주기
d = left_dir
# move_ahead(x, y, dir):
def move_ahead(x, y, dir):
# 전역 변수 선언
global r, c
# dxs dys 북 동 남 서 순
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]
# 다음 위치
nx, ny = x + dxs[dir], y + dys[dir]
# 옮겨주기
r, c = nx, ny
# 설계
# cleaned_area
cleaned_area = [
[0] * m
for _ in range(n)
]
# 청소기 시작 위치 청소
cleaned_area[r][c] = 1
while True:
# 네 방향 모두 청소 되어있거나 벽이면서,
# 뒤쪽 방향이 벽이라 후진 할 수 없는 경우
if all_cleaned_or_wall(r, c) and back_is_wall(r, c, d):
# 청소 끝남
break
# 네 방향 모두 청소 되어있거나 벽이지만,
# 뒤쪽 방향이 갈 수 있으면,
elif all_cleaned_or_wall(r, c) and not back_is_wall(r, c, d):
# 한 칸 후진
step_back(r, c, d)
# 왼쪽 방향이 벽이 아니고,
# 아직 청소하지 않은 공간이 존재한다면,
elif not left_is_wall(r, c, d) and left_is_dirty(r, c, d):
# 왼쪽으로 회전한 다음,
turn_left(d)
# 한 칸 전진하고,
move_ahead(r, c, d)
# 현재 위치 청소
cleaned_area[r][c] = 1
# 욎쪽 방향이 벽이거나,
# 이미 청소된 구역이라면
elif left_is_wall(r, c, d) or not left_is_dirty(r, c, d):
# 왼쪽으로 회전
turn_left(d)
# 정답용
area = 0
# 청소된 구역을 돌면서
for i in range(n):
for j in range(m):
# 답을 더해줌
area += cleaned_area[i][j]
# 출력
print(area)
'Algorithm(BOJ, Python) > Simulation' 카테고리의 다른 글
[백준_2174] 로봇 시뮬레이션 python (2) | 2022.09.16 |
---|---|
[백준_14499] 주사위굴리기 python (0) | 2022.09.04 |
[백준_5215] 지구온난화 python (0) | 2022.08.09 |
[백준_1063] 킹 python (0) | 2022.08.04 |
[백준_8911] 거북이 python (0) | 2022.08.03 |