구현을 하는 시뮬레이션 문제이다.
시뮬레이션 문제는 문제의 요구사항을 깔끔하게 정리하고 함수로 만들어야 구현이 깔끔해지고 후에 어디서 틀렸는지 쉽게 알 수 있는 것 같다.
문제에서는 말의 번호대로 계속 움직이는 함수를 실행시키고, 말을 움직였다면 해당 칸에 말이 얼마나 쌓여있는지 보면 된다.
문제를 해결하기 위해선
말이 얼마나 쌓여있는지를 알기위한 칸마다의 말을 쌓아놓을 배열이 필요하고,
말이 움직일 때마다 말의 움직인 위치를 트래킹해야 한다.
문제 해결 과정은,
반복문을 통해 말을 하나씩 움직이는 함수를 실행하고,
함수가 게임의 종료를 알린다면, 몇턴이 지났는지를 반환하면 된다.
어떤 말을 움직인다고 할때, 파란색칸이나, 벽을 만난다면 일단 방향을 바꿔놓고 생각해야한다. 방향을 바꾸고 나서는 파란색칸이던지, 빨간칸인지, 흰칸인지 세가지 경우의 수가 있다.
방향을 바꾸고 나서 파란칸이면 방향만 바꿔주고 함수를 끝내면 되고, 그렇지 않다면 흰칸이나 빨간칸일때 실행되는 로직으로 넘어가면 된다.
넘긴 후에는, 해당 칸에있는 말의 위치를 변경해주면 된다.
n,k = list(map(int,input().split()))
board = []
horses = []
board2 = [[[]*n for i in range(n)] for i in range(n)]
ans = 0
for i in range(n):
tmp = list(map(int,input().split()))
board.append(tmp)
horses.append([0,0,0])
for i in range(k):
horse = list(map(int,input().split()))
horse[0] -= 1
horse[1] -= 1
horse[2] -= 1
board2[horse[0]][horse[1]].append(i+1)
horses.append(horse)
dx = [0,0,-1,1]
dy = [1,-1,0,0]
def move(hidx):
x,y,d = horses[hidx] ## idx에 해당하는 말 꺼내기
nx = x + dx[d]
ny = y + dy[d]
if not 0 <= nx < n or not 0<= ny < n or board[nx][ny] == 2: ## 나가거나 파란색일때
if d < 2:
d = (d+1) % 2
else:
d = (d+1) % 2
d += 2
nx = x + dx[d] ## 방향 바꾸기
ny = y + dy[d]
horses[hidx][2] = d ## 말 배열 update
if not 0 <= nx < n or not 0<= ny < n or board[nx][ny] == 2: ##방향 바꾸고 이동해도 파란색이면
return 0
## 한칸 이동
idx = board2[x][y].index(hidx) ## 이동 전 칸에서 말 인덱스 찾기
s = board2[x][y][idx:]
board2[x][y] = board2[x][y][:idx] ## 이동 전칸 변경
if board[nx][ny] == 1: ## 빨간색이면
s.reverse()
board2[nx][ny].extend(s)
for i in board2[nx][ny]:
horses[i][0] = nx
horses[i][1] = ny
if len(board2[nx][ny]) >= 4: ## 게임 종료
return 1
while ans < 1000:
ans += 1
for i in range(1,k+1):
if move(i):
print(ans)
exit(0)
print(-1)