문제에 나와있는 순서대로만 구현하면
풀리는 문제!
빈칸 : 0, 벽 : 1, 청소한 칸 : 2로 구분하였다.
처음에는 청소한 구역도 1로 처리했는데
이렇게 하면 2번의 c,d조건을 판별할 수 없었다.
그리고
1번이랑 2번을 각각 독립적으로 움직이게끔
하는 과정이 살짝 버거웠다 ㅎ..
그리고 % 연산자를 활용해야 하는 부분을 잘 기억해야한다..
매번 헷갈리지만 ^0^
왼쪽 방향으로 돌릴 땐 (d+3)%4로 해주면 되는데,
d에 3을 더하는 이유에 대해 알아야
앞으로도 사용해먹을 수 있을 것 같아서
상세하게 풀어써보기!
방향은 0, 1, 2, 3 이렇게 있다.
3에서 왼쪽으로 움직이면 2가 되어야하는데 이때는 -1을 해주면 된다.
그러나 문제가 있다.
0에서 왼쪽으로 움직이면 방향은 3이 되어야한다.
그래서 -1을 해주면 위 경우에서 오류가 나게 된다.
(d+3)%4를 해주면
(0+3)%4 = 3이 된다!
만약 2만큼 회전시켜야 한다고 하면?
현재 방향과 반대되는 방향의 숫자
즉, 0이 2가 되게 하는 방법은 간단하다.
(d+2)%4를 해주면 된다.
즉, (d+(n-움직이고자 하는 방향 수))%n을 해주면 된다 - !
실행시간은 112ms
다른 사람들 코드 보면서
배워야겠다 :)
# 북(0),동(1),남(2),서(3) (오른쪽,왼쪽,아래,위)
from collections import deque
from copy import deepcopy
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
n, m = map(int, input().split())
r, c, d = map(int, input().split())
array = [list(map(int, input().split())) for _ in range(n)]
answer = 0
def second(cnt):
global r, c, d
for i in range(4):
nd = (d + 3) % 4
nr = r + dx[nd]
nc = c + dy[nd]
if 0 <= nr < n and 0 <= nc < m:
# a. 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
if array[nr][nc] == 0: # 방문하지 않은 곳
r = nr
c = nc
d = nd
return cnt
# b. 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
else:
cnt += 1
d -= 1
return cnt
# 빈칸 : 0, 벽 : 1, 청소 : 2
while True:
# 1. 현재 위치를 청소한다.
if array[r][c] == 0:
array[r][c] = 2
answer += 1
cnt = 0
# 2. # 2. 현재 위치에서 현재 방향을 기준으로 왼쪽 방향부터 차례대로 인접한 칸을 탐색한다
cnt = second(cnt)
if cnt == 4:
nd = (d + 2) % 4
nr = r + dx[nd]
nc = c + dy[nd]
# d. 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
if array[nr][nc] == 1:
print(answer)
break
# c. 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
else: # (뒷편이 벽이 아닐 경우)
r = nr
c = nc
다른 사람들 풀이를 보니까
훨씬 간단하게 했던데..
내 코드가 지저분해보이는 마법
1초도 걸리지 않았따..
다른 코드 참고해서
고쳐본 코드!
실행시간 68ms이당..!
두번째 과정을 따로 함수로 빼줄 필요도 없었다.처음에 시작하기 전에 현재 위치를 청소해놓고while문을 시작한다.
check 변수를 통해사방이 다 막혀잇는지 아닌지 체크한다.i==3이면서 check의 값이 0이면? -> 4방향이 벽이거나 청소한 곳이라는 거!
만약 뒷쪽에 있는 값이 1일 경우에는벽으로 막혀있으니 지나갈 수 없다.반복문 종료
1이 아니면? 청소했던 곳이라는 얘기니까지나갈 수는 있다청소를 또 못할 뿐!
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
n, m = map(int, input().split())
r, c, d = map(int, input().split())
array = [list(map(int, input().split())) for _ in range(n)]
answer = 1
array[r][c] = 2
while True:
for i in range(4):
nd = (d + 3) % 4
nr = r + dx[nd]
nc = c + dy[nd]
if array[nr][nc] == 0:
array[nr][nc] = 2
answer += 1
r = nr
c = nc
d = nd
check = 1
break
else:
d-=1
check = 0
if i == 3 and check == 0: # 4방향 다 갈 수 없는 상태인 경우
nd = (d + 2) % 4
nr = r + dx[nd]
nc = c + dy[nd]
if array[nr][nc] == 1: # 벽
break
else: # 후진
r = nr
c = nc
print(answer)
'여니의 취준 준비 > 코딩테스트 (Python)' 카테고리의 다른 글
[n1236] 성 지키기 in python (0) | 2021.10.27 |
---|---|
[n15686] 치킨 배달 in python (0) | 2021.10.23 |
[n6603] 로또 in python (0) | 2021.10.21 |
[n14248] 점프 점프 in python (0) | 2021.10.20 |
[n14889] 스타트와 링크 in python (0) | 2021.10.20 |