(Python/파이썬) - 백준(BOJ) 2344번 : 거울
https://www.acmicpc.net/problem/2344
- 문제 :
세로 N, 가로 M 크기의 상자가 있다. 이 상자 안에는 몇 개의 거울이 들어 있다. 상자를 위에서 봤을 때, 거울은 한 칸 안에 대각선 모양으로 들어있다고 한다. 또, 상자의 테두리를 따라서 칸마다 구멍이 뚫려 있다. 편의상 구멍은 왼쪽 위에 뚫려있는 것부터 시계 반대 방향으로 1, 2, …, 2N+2M 의 번호가 붙어 있다. 예를 들어 다음과 같은 경우를 보자.
이제 이 상자에 뚫려있는 구멍으로 빛을 쏜다고 생각해보자. 1번 구멍으로 쏠 경우에는 (1, 2)의 위치에 있는 거울에 반사되어 9번 구멍으로 빛이 가게 된다. 또, 2번 구멍으로 빛을 쏠 경우에는 (2, 2)의 위치에 있는 거울과 (1, 2)에 있는 거울에 차례로 반사되어 7번 구멍으로 빛이 나가게 된다.
이와 같이 상자의 모양이 주어졌을 때, 각 구멍으로 쏜 빛이 나가게 되는 구멍을 구하는 프로그램을 작성하시오.
- 풀이 :
2차원 배열에서의 구현 문제였습니다.
풀이입니다.
1. 반시계방향으로 오른쪽 방향의 (0,0) 부터 아래쪽 방향의 (0,0)까지 탐색하기 위해 for문을 사용하여 4 방향 케이스를 구현했습니다.
2. 각각의 입력 방향과 좌표에 대해 search함수를 실행합니다. search함수는 빛이 board의 바깥으로 벗어나면 해당 방향의 번호를 반환합니다.
3. search 함수에서 빛이 진행할 때 거울을 만났다면 빛이 반사되는 방향으로 direction을 변경해줍니다. 반사 방향은 입사 방향에 따라 고정되어 있으므로 배열로 사용했습니다.
4. out 함수를 사용하여 배열에서 벗어나는 좌표가 문제에서 요구하는 몇 번 방향인지 계산하여 반환합니다.
- 소스코드 :
import sys
input = sys.stdin.readline
dx = [-1,0,1,0]
dy = [0,1,0,-1]
dir = [1,0,3,2]
def out(x,y): # 빛이 나가는 좌표에 따른 번호
if x == -1:
return 2*N + 2*M -y
elif y == -1:
return x+1
elif x == N:
return N + y + 1
else:
return 2*N + M - x
def search(start,direction):
x,y = start
while 0 <= x < N and 0 <= y < M:
if board[x][y] == 1: #거울이 있다면 빛의 진행경로 변경
direction = dir[direction]
x += dx[direction]
y += dy[direction]
return str(out(x,y))
N,M = map(int,input().split())
board = [list(map(int,input().split())) for _ in range(N)]
answer = []
# 1번부터 2N + 2M번까지 입력 순서대로 실행
for i in range(N):
direction = 1
answer.append(search([i,0],direction))
for i in range(M):
direction = 0
answer.append(search([N-1, i], direction))
for i in range(N-1,-1,-1):
direction = 3
answer.append(search([i, M-1], direction))
for i in range(M-1,-1,-1):
direction = 2
answer.append(search([0, i], direction))
print(' '.join(answer))