문제
https://www.acmicpc.net/problem/14503
사용 언어
Python3
풀이 과정
처음에 나는 d(현재 바라보고 있는 방향)에 따라서 다음 좌표값을 다르게 설정해주려 했는데, 그럼 왼쪽으로 회전할 때 뒤로 갈 때 등의 좌표값을 모두 조건문으로 나눠줘야 했다.
if d == 0: # 북쪽의 왼쪽
next = (r, c-1)
elif d == 1: # 동쪽의 왼쪽
next = (r-1, c)
elif d == 2: # 남쪽의 왼쪽
next = (r, c+1)
elif d == 3: # 서쪽의 왼쪽
next = (r+1, c)
if d == 0: # 북쪽의 뒤쪽
next = (r+1, c)
elif d == 1: # 동쪽의 뒤쪽
next = (r, c-1)
elif d == 2: # 남쪽의 뒤쪽
next = (r-1, c)
elif d == 3: # 서쪽의 뒤쪽
next = (r, c+1)
너무 비효율적인 것 같고 구현하다가 머리가 로봇청소기 마냥 빙빙 돌기도 해서 아쉽지만 다른 블로그를 참고했다.😥역시 델타값(?)을 사용하는 게 가장 깔끔한 것 같은데 아직 내가 코드에 적용하는게 어려운 것 같다.
dx = [-1,0,1,0]
dy = [0,1,0,-1]
구현 문제는 시간을 더~~~ 많이 두고 풀었으면 풀 수 있었을 지 모르나 그 시간에 다른 문제를 더 푸는게 좋다고 생각한다... 어쨌든 내가 수정할 부분은 수정해서 본 맞았습니다!! 시간이 생각보다 짧아서 신기했다.
+) 2022-04-08에 추가
스터디원의 코드리뷰를 참고하여 turnleft()함수를 그냥 while문 안으로 넣었더니 시간이 꽤 줄어들었다.
그리고 다른 곳에서 배운대로 % 연산자를 이용하여 20번째 줄도 수정했다.
수정한 코드는 아래 제출 답안에 반영해두었다.
제출 답안
import sys
N, M = map(int, sys.stdin.readline().strip().split())
r, c, d = map(int, sys.stdin.readline().strip().split())
coordinate = []
for _ in range(N):
coordinate.append(list(map(int, sys.stdin.readline().strip().split())))
isVisited = [([False] * M) for _ in range(N)]
isVisited[r][c] = True # 현재 위치 방문
# 0: 위쪽 이동, 1: 오른쪽 이동, 2: 아래 이동, 3: 왼쪽 이동
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
cleaned = 1 # 현재 위치 항상 청소하고 시작
turnTime = 0 # 왼쪽으로 회전한 횟수
while True:
# 0 : 북, 1 : 동, 2 : 남, 3 : 서
d = (d - 1) % 4 # 왼쪽으로 회전, -1 % 4 = 3
nx = r + dx[d] # 회전한 방향으로 이동
ny = c + dy[d] # 회전한 방향으로 이동
if isVisited[nx][ny] == 0 and coordinate[nx][ny] == 0: # 이동을 했는데 방문하지 않았고 빈 공간인 경우
isVisited[nx][ny] = True # 방문 처리
cleaned += 1 # 청소 횟수 증가
turnTime = 0 # 왼쪽 방향 회전 횟수 0으로 초기화
r = nx # 위치 이동
c = ny # 위치 이동
continue # 반복
else: # 이동이 불가능 한 경우 왼쪽 방향 회전 횟수만 증가
turnTime += 1
if turnTime == 4: # 총 4번 회전 한 경우, 네 방향 모두 청소가 되어 있거나 벽이 있는 경우
nx = r - dx[d] # 뒤로 이동
ny = c - dy[d] # 뒤로 이동
if coordinate[nx][ny] == 0: # 이동한 위치가 벽이 아니라면
r = nx # 이동
c = ny # 이동
else: # 그렇지 않으면
break # 작동을 멈춤
turnTime = 0 # 왼쪽 방향 회전 횟수 초기화
print(cleaned) # 청소 횟수 출력
공부한 내용
파이썬의 삼항연산자
최근에 자바스크립트를 사용하다 보니 습관적으로 ~?~:~ 형식으로 삼항연산자를 사용하려 했는데
파이썬은 좀 더 직관적이지 못한 삼항연산자 방식을 쓰는 것 같다. (항상 파이썬이 제일 직관적이라고 생각했는데 띠용)
어쨌든 이 방식도 익숙해지려고 해야겠다.
[true_value] if [condition] else [false_value] // 파이썬 방식
출처: https://m.blog.naver.com/wideeyed/221858874414
음수에 % 연산자를 사용하면?
+) 2022-04-08에 추가
이 문제를 풀면서 -1이 3으로 초기화되어야 하는 상황에서 나는 삼항연산자를 사용했고, 그래서 위에 공부한 내용이라고도 써두었지만 알고보니 % 연산자를 사용하면 아주 간단히 해결될 문제였다.
음수에 %연산자를 사용해도 나머지는 0이나 자연수가 되어야 한다.
따라서
4 * (-1) + 3 = -1 // 몫 -1 나머지 3
150 * (-2) + 100 = -200 // 몫 -2 나머지 100
와 같이 나머지가 구해진다.
이를 음수일 경우 마지막 숫자로부터 초기화 되는 경우에 적용할 수 있다.
'코딩 테스트 스터디 > 백준' 카테고리의 다른 글
[실버 III] 2630번. 색종이 만들기 (0) | 2022.04.07 |
---|---|
[실버 III] 2606번. 바이러스 (0) | 2022.04.06 |
[실버 IV] 4881번. 자리수의 제곱 (0) | 2022.04.05 |
[실버 IV] 24060번. 알고리즘 수업 - 병합 정렬 1 (0) | 2022.02.23 |
[실버 V] 16171번. 나는 친구가 적다 (Small) (0) | 2022.02.23 |