📃 문제
코드트리 - 꼬리잡기놀이
풀이
사용한 배열
- 팀원의 위치 정보 arr (N * N)
- 팀원들의 동선 move_arr (N * N)
- 모든 팀의 팀원들 위칫값을 담은 배열 total_team (팀원 수 * M)
순서
- 각 팀의 팀원들 위칫값 및 동선을 먼저 저장한다.
- 라운드를 체크하여 공의 시작 위치와 던지는 방향을 체크한다.
- 팀 이동을 진행한다.
- 머리사람의 이동을 기반으로 위치 최신화
- total_team 최신화
- 공을 던져서 맞는 사람 체크한다.
- arr과 total_team 방향 바꾸기 최신화
- 라운드 반복
코드
import sys
input = sys.stdin.readline
def dfs(x, y, numero):
"""
팀원 위치와 팀 동선 체크
:param x, y: 머리사람(1)의 위치
:param numero: 팀 번호
"""
global search_all_teammate
move_arr[x][y] = numero
for d in range(4):
nx, ny = x + dx[d], y + dy[d]
if 0 <= nx < N and 0 <= ny < N and move_arr[nx][ny] != numero:
if arr[nx][ny] == 0: continue
if arr[nx][ny] == 2:
team.append((nx, ny))
elif arr[x][y] + 1 == 3:
search_all_teammate = True
team.append((nx, ny))
elif not search_all_teammate: continue
dfs(nx, ny, numero)
def head_move(head, numero):
"""
머리사람이 가야할 곳 체크
:param head: 머리사람 위치
:param numero: 팀 번호
:return: 머리사람이 가야할 위치
"""
x, y = head
for d in range(4):
nx, ny = x + dx[d], y + dy[d]
if 0 <= nx < N and 0 <= ny < N and move_arr[nx][ny] == numero:
if arr[nx][ny] == 4 or arr[nx][ny] == 3:
return nx, ny
def team_move(numero):
"""
팀원 위칫값 담은 리스트(total_team) 최신화
전체 배열(arr) 최신화
:param numero: 팀 번호
"""
team = total_team[numero]
nx, ny = head_move(team[0], numero)
x, y = team.pop()
arr[x][y] = 4
for x, y in team:
arr[x][y] = 2
x, y = team[-1]
arr[x][y] = 3
arr[nx][ny] = 1
total_team[numero] = [(nx, ny)] + team
def ball_check(x, y, d):
"""
공 던져서 만나는 사람 찾기
:param x, y: 공의 시작 위치
:param d: 공 방향 인덱스
"""
global ans
for n in range(N):
if arr[x][y] == 0 or arr[x][y] == 4:
x += dx[d]
y += dy[d]
continue
numero = move_arr[x][y]
team = total_team[numero]
for k in range(len(team)):
if team[k] == (x, y):
ans += (k + 1) ** 2
head_x, head_y = team[0]
tail_x, tail_y = team[-1]
arr[head_x][head_y] = 3
arr[tail_x][tail_y] = 1
total_team[numero].reverse()
return
dx = [0, -1, 0, 1]
dy = [1, 0, -1, 0]
N, M, K = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
numero = 1
move_arr = [[0] * N for _ in range(N)]
total_team = [[0]]
for i in range(N):
for j in range(N):
if arr[i][j] == 1:
search_all_teammate = False
team = [(i, j)]
dfs(i, j, numero)
total_team.append(team)
numero += 1
ans = 0
d = 3
ball_x = ball_y = 0
n = 0
for k in range(K):
if n == N:
d = (d + 1) % 4
n = 0
elif n != 0:
ball_x += dx[d]
ball_y += dy[d]
for numero in range(1, M+1):
team_move(numero)
ball_check(ball_x, ball_y, (d + 1) % 4)
n += 1
print(ans)
느낀 점
- 문제가 길고 조건이 많아도 전체적으로 정리를 다 하고 코드를 작성하자😂😂😂
- 의사코드(pseudo-code) 꼭❗