728x90
시간 제한 1초, 메모리 제한 512MB
# 조건
- 마법사 상어가 크기가 N×N인 격자에 파이어볼 M개를 발사했다.
- 가장 처음에 파이어볼은 각자 위치에서 이동을 대기하고 있다.
- i번 파이어볼의 위치는 (ri, ci), 질량은 mi이고, 방향은 di, 속력은 si이다. 위치 (r, c)는 r행 c열을 의미한다.
- 격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다.
- 파이어볼의 방향은 어떤 칸과 인접한 8개의 칸의 방향을 의미하며, 정수로는 다음과 같다.
마법사 상어가 모든 파이어볼에게 이동을 명령하면 다음이 일들이 일어난다.
- 모든 파이어볼이 자신의 방향 di로 속력 si칸 만큼 이동한다.
- 이동하는 중에는 같은 칸에 여러 개의 파이어볼이 있을 수도 있다.
- 이동이 모두 끝난 뒤, 2개 이상의 파이어볼이 있는 칸에서는 다음과 같은 일이 일어난다.
- 같은 칸에 있는 파이어볼은 모두 하나로 합쳐진다.
- 파이어볼은 4개의 파이어볼로 나누어진다.
- 나누어진 파이어볼의 질량, 속력, 방향은 다음과 같다.
- 질량은 ⌊(합쳐진 파이어볼 질량의 합)/5⌋이다.
- 속력은 ⌊(합쳐진 파이어볼 속력의 합)/(합쳐진 파이어볼의 개수)⌋이다.
- 합쳐지는 파이어볼의 방향이 모두 홀수이거나 모두 짝수이면, 방향은 0, 2, 4, 6이 되고, 그렇지 않으면 1, 3, 5, 7이 된다.
- 질량이 0인 파이어볼은 소멸되어 없어진다.
마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 구해보자.
입력
- 첫째 줄에 N, M, K가 주어진다.
- 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다.
- 서로 다른 두 파이어볼의 위치가 같은 경우는 입력으로 주어지지 않는다.
출력
- 마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 출력한다.
제한
- 4 ≤ N ≤ 50
- 0 ≤ M ≤ N2
- 1 ≤ K ≤ 1,000
- 1 ≤ ri, ci ≤ N
- 1 ≤ mi ≤ 1,000
- 1 ≤ si ≤ 1,000
- 0 ≤ di ≤ 7
# 접근 방법
- 삼성 SW 역량테스트 기출이다 -> 구현 시뮬레이션!
- 문제를 잘 읽고 조건을 잘 정리하는 것이 관건.
- fireball과 arr 배열을 만들어주고 배열이 1부터 시작하므로
- fireball은 r과 c를 -1 씩 해주고 append한다.
- for 반복문
- K 만큼 반복하면서
- while fireball을 통해 모든 fireball을 이동시켜준다. (arr에 추가)
- 이후, arr을 순회하면서 길이가 2이상인 경우와 1인 경우를 나눠서 구해준다.
- 2이상인 경우
- 무게 합, 속력 합, 홀수, 짝수, 전체 개수 변수를 생성해준 후
- 해당 arr 을 while문을 통해 반복한다.
- fireball을 pop을 통해 꺼내주고 무게, 속력, 홀짝 카운트를 누적합해준다.
- 홀의 수 또는 짝의 수가 전체 길이와 같다면 nd = [0 2 4 8]
- 아니라면 1 3 5 7의 방향을 가지게 되므로 리스트로 생성해준다.
- 질량합 // 5가 0이라면 소멸, 아니라면 nd 카운트를 순회하면서 fireball에 추가해준다. -> 방향은 nd 값
- 1인 경우
- fireball에 그냥 추가해주기
- 이후 질량 합만 더하면 된다.
import sys
sys.stdin = open('input.txt')
from collections import defaultdict
N, M, K = map(int, input().split())
arr = [[[] for _ in range(N)] for _ in range(N)]
fireball = []
# 방향
di, dj = [-1, -1, 0, 1, 1, 1, 0, -1], [0, 1, 1, 1, 0, -1, -1, -1]
for _ in range(M):
r, c, m, s, d = map(int, input().split())
fireball.append((r-1, c-1, m,s,d))
for _ in range(K):
while fireball:
cr, cc, cm, cs, cd = fireball.pop()
# 1번과 N번이 연결되어 있으므로 %로 나눠준다.
nr = (cr + cs * di[cd]) % N
nc = (cc + cs * dj[cd]) % N
arr[nr][nc].append([cm, cs, cd])
# 2개 이상인지 체크
for r in range(N):
for c in range(N):
if len(arr[r][c]) >= 2:
# 4개로 쪼개기
val_m, val_s, cnt_odd, cnt_even, cnt = 0, 0, 0, 0, len(arr[r][c])
while arr[r][c]:
m, s, d = arr[r][c].pop()
val_m += m
val_s += s
if d % 2:
cnt_odd += 1
else:
cnt_even += 1
if cnt_odd == cnt or cnt_even == cnt:
nd = [0, 2, 4, 6]
else:
nd = [1, 3, 5, 7]
if val_m // 5:
for i in nd:
fireball.append([r, c, val_m//5, val_s//cnt, i])
elif len(arr[r][c]) == 1:
fireball.append([r, c] + arr[r][c].pop())
print(sum(i[2] for i in fireball))
728x90
'ALGORITHM > 정렬, 탐색,구현' 카테고리의 다른 글
[코드트리] 파이썬 - 코드트리 빵 (0) | 2023.04.09 |
---|---|
[코드트리] 파이썬 - 예술성 (0) | 2023.04.07 |
[백준 14503번] 파이썬 - 로봇 청소기 (0) | 2023.04.04 |
[백준 20922번] 파이썬 - 겹치는 건 싫어 (0) | 2023.04.02 |
[백준 1141번] 파이썬 - 접두사 (0) | 2023.03.29 |