728x90

코드트리 - 핀볼게임

풀이시간 25분

# 접근 방법

  • dx, dy 테크닉이 중요한 문제이다.
  • 1번과 2번 벽을 만났을 때 어떻게 진행시키는지가 중요하다.
  • di, dj = [1, 0, -1, 0], [0, 1, 0, -1]로 설정해주며
    • 1번을 만난 경우와 2번을 만난 경우를 각각 회전하는 딕셔너리를 만들어준다.
first = {0:3, 1:2, 2:1, 3:0}
second = {0:1, 1:0, 2:3, 3:2}
  • 0행에서 진행, 0번째 열 기준 진행, N-1번째 행 기준 진행, N-1번째 열 기준 진행을 해주면 된다.
  • 주의할 점은, 들어가는 시간과 나오는 시간을 포함해주어야 한다는 것과 시작 위치마다 핀볼의 시작 진행 방향이 다르다는 것이다.
  • 들어갈 때부터 카운트를 해주고 이동하는 것을 편하게 하기 위하여 각 진행 방향의 -1을 해주고 시작한다.
    • 1, 0에서 핀볼을 굴린다면 오른쪽 진행이므로 1, -1에서 시작
  • pin_ball 함수
    • 시간을 += 1해주고
    • ni, nj = si+di[d], sj+dj[d]를 통하여 이동할 칸을 탐색해준다.
    • 만약, 범위 밖이라면 그대로 종료해주고 시간을 비교해주면 된다.
    • 그렇지 않다면 1번, 2번 벽을 만난 경우 d를 변화시키고
    • 현재 위치를 si, sj = ni, nj로 변경시키며 이동해준다.
import sys  
N = int(input())  
arr = [list(map(int, input().split())) for _ in range(N)]  

# 하 좌 상 우  
di, dj = [1, 0, -1, 0], [0, 1, 0, -1]  

result = 0  
first = {0:3, 1:2, 2:1, 3:0}  
second = {0:1, 1:0, 2:3, 3:2}  
# 시작 행, 열, 방향  
def pin_ball(si, sj, d):  
    global result  
    # 들어오고 나가는 것 포함해야되는 것 주의  
    time = 0  
    while True:  
        time += 1  
        ni, nj = si+di[d], sj+dj[d]  
        if not 0<=ni<N or not 0<=nj<N:  
            break  
        if arr[ni][nj] == 1:  
            d = first[d]  
        elif arr[ni][nj] == 2:  
            d = second[d]  
        si, sj = ni, nj  
    if time > result:  
        result = time      

#0행 기준 진행(위에서 아래 시작)  
#0열 기준 진행  
#N-1행 기준 진행  
#N-1열 기준 진행  
for j in range(N):  
    pin_ball(-1, j, 0)  
    pin_ball(j, -1, 1)  
    pin_ball(N, j, 2)  
    pin_ball(j, N, 3)  
print(result)
728x90