[Gold IV]
https://www.acmicpc.net/problem/20056
20056번: 마법사 상어와 파이어볼
첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치
www.acmicpc.net
풀이
지시하는 대로 구현하면 어렵지 않게 풀이할 수 있는 구현 문제.
파이어볼이 이동할 때 MOD연산을 활용하는 것과
질량이 0이 된 파이어볼을 제대로 제거하는 것에 유의하자.
AC.
N, M, K = map(int, input().split()) # 방향 (r이동량, c이동량) directions = [[-1, 0], [-1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1]] fireballs = [] for i in range(M): fireballs.append(list(map(int, input().split()))) # 이동 후 파이어볼의 위치를 나타내기 위한 그래프(격자) graph = [[[] for _ in range(N)] for _ in range(N)] def move(g): for i, fireball in enumerate(fireballs): r, c, m, s, d = fireball dr, dc = directions[d] # 이동량 계산 및 MOD 연산을 통한 1번-N번 행/열 연결. r = (r + dr * s) % N c = (c + dc * s) % N # 이동 후 좌표 갱신 fireballs[i][0] = r fireballs[i][1] = c # 이동 후 위치 저장 g[r][c].append(i) def collision(g): newBalls = [] delIndex = [] for r in range(N): for c in range(N): balls = g[r][c] # 칸에 있는 파이어볼이 2개 이상이면 if len(balls) > 1: # 합쳐진 파이어볼은 지우기 위해 저장 delIndex.extend(balls) # 질량 계산 mass = 0 for i in balls: mass += fireballs[i][2] mass = mass//5 if mass == 0: continue # 속력 계산 speed = 0 for i in balls: speed += fireballs[i][3] speed = speed//len(balls) # 방향 계산 direction = 0 for i in balls: direction += fireballs[i][4] % 2 # 파이어볼 나누기 # 방향을 2로 나눈 나머지를 모두 더한 값이 0이거나 파이어볼의 개수와 같다면, # 방향이 모두 홀수이거나 짝수인 것. if direction == 0 or direction == len(balls): for d in range(0, 8, 2): newBalls.append([r, c, mass, speed, d]) else: for d in range(1, 9, 2): newBalls.append([r, c, mass, speed, d]) # 지우기 위해 저장했던 합쳐진 파이어볼 지우기 delIndex = sorted(delIndex, reverse=True) for i in delIndex: del fireballs[i] # 새로운 파이어볼 추가 fireballs.extend(newBalls) # K회 실행 for _ in range(K): move(graph) collision(graph) # 그래프 초기화 graph = [[[] for _ in range(N)] for _ in range(N)] result = 0 for i in range(len(fireballs)): result += fireballs[i][2] print(result)