https://www.acmicpc.net/problem/20056
격자 n * n
파이어볼 개수 m개
파이오볼은 위치 질량 방향 속력을 가짐
행열은 1,1부터 시작함
1번열과 n번열은 연결되어 있음
입력
- 첫 번째 줄 : nn, ll, kk
nn : 격자 크기
ll : 초기 파이어볼 개수
kk : 이동 명령 횟수
- 나머지 줄 : rr cc mm ss dd
rr : 행
cc : 열
mm : 질량
ss : 속력
dd : 방향
출력
남아있는 파이어볼 질량의 합
시뮬레이션이므로 문제에 주어진 조건을 그대로 구현하면 됩니다.
dx = [-1, -1, 0, 1, 1, 1, 0, -1]
dy = [0, 1, 1, 1, 0, -1, -1, -1]
def print_arr(arrs):
for i in range(len(arrs)):
for j in range(len(arrs)):
print(arrs[i][j], end=" ")
print()
def move():
global nn
for i in range(len(li)):
rr, cc, mm, ss, dd = li[i]
nx = rr + dx[dd] * ss
ny = cc + dy[dd] * ss
if nx < 0:
nx = (abs(nx) % nn) * -1
nx = nx + nn
if ny < 0:
ny = (abs(ny) % nn) * -1
ny = ny + nn
if nx >= nn:
nx = nx % nn
if ny >= nn:
ny = ny % nn
if arr[nx][ny] == -1:
arr[nx][ny] = i
add_list[i].append(i)
loc_list[i].extend([nx, ny])
else:
add_list[arr[nx][ny]].append(i)
# print_arr(arr)
# print(add_list)
def ball_merge():
for i in range(len(add_list)):
# 내 위치는 나만 있는 경우
if len(add_list[i]) == 1:
rr, cc, mm, ss, dd = li[i]
new_rr = loc_list[i][0]
new_cc = loc_list[i][1]
next_li.append([new_rr, new_cc, mm, ss, dd])
elif len(add_list[i]) == 0:
continue
# 합쳐지는 경우
else:
add_rr = loc_list[i][0]
add_cc = loc_list[i][1]
add_mm = 0
add_ss = 0
add_dd = li[add_list[i][0]][4]
is_dd_same = True
# 합치기
for j in range(len(add_list[i])):
now = add_list[i][j]
now_rr, now_cc, now_mm, now_ss, now_dd = li[now]
add_mm += now_mm
add_ss += now_ss
if is_dd_same == False:
continue
if now_dd % 2 != add_dd % 2:
is_dd_same = False
# 나누기
add_mm = add_mm // 5
add_ss = add_ss // len(add_list[i])
# 0이라면 소멸
if add_mm == 0:
continue
# 모든 방향이 동일하면
if is_dd_same == True:
for j in range(0, 7, 2):
next_li.append([add_rr, add_cc, add_mm, add_ss, j])
else:
for j in range(1, 8, 2):
next_li.append([add_rr, add_cc, add_mm, add_ss, j])
nn, ll, kk = list(map(int, input().split()))
li = []
for i in range(ll):
rr, cc, mm, ss, dd = (list(map(int, input().split())))
li.append([rr - 1, cc - 1, mm, ss, dd])
# 이동 명령 횟수만큼 반복
for z in range(kk):
add_list = [[] for i in range(len(li))] # 리스트의 i번째 위치 볼과 합쳐질 볼
loc_list = [[] for i in range(len(li))]
arr = [[-1] * nn for i in range(nn)] # 이동한 위치 찍기
next_li = []
# 이동
move()
# 합치기
ball_merge()
li = next_li
ans = 0
for i in range(len(li)):
ans += li[i][2]
print(ans)
이 문제에서 가장 헷갈렸던 부분은 파이어볼을 나눌 때 위치는 그대로이고 방향이 서로 다른 4개의 파이어볼을 만들어야 한다는 점이었습니다.
문제를 명확하게 이해하고 푸는게 중요합니다.
해당 코드는 에디터가 코드 연습을 위해 직접 작성하였습니다.
혹시 오류가 있거나 더 좋은 코드 방향성을 아시는 분은 댓글로 남겨주시면 감사하겠습니다!
python source : https://github.com/ssh5212/conding-test-practice
java source : https://github.com/ssh5212/coding-test-java
[BOJ / 백준] 2805 나무 자르기 (S2^ / 이분탐색) - Python (1) | 2024.06.18 |
---|---|
[BOJ / 백준] 20055 컨베이어 벨트 위의 로봇 (G5 / 시뮬레이션) - Python (0) | 2024.06.16 |
[코드트리] 고대 문명 유적 탐사 (G4^ / 시뮬레이션) - Python (0) | 2024.06.15 |
[BOJ / 백준] 11559 Puyo Pyuo (G4 / 시뮬레이션, BFS) - Python (0) | 2024.06.14 |
[Baekjoon] 백준 N과 M 시리즈 1~4 (S3 / 순조부) - JS (2) | 2023.10.23 |