Skip to content

Commit 25af2f2

Browse files
committed
[BOJ] 마법사 상어와 비바라기 / 골드5 / 70분
https://www.acmicpc.net/problem/21610
1 parent f74af1f commit 25af2f2

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
'''
2+
비바라기를 시전하면 (N, 1), (N, 2), (N-1, 1), (N-1, 2)에 비구름이 생긴다. 구름은 칸 전체를 차지한다. 이제 구름에 이동을 M번 명령하려고 한다. i번째 이동 명령은 방향 di과 거리 si로 이루어져 있다. 방향은 총 8개의 방향이 있으며, 8개의 정수로 표현한다. 1부터 순서대로 ←, ↖, ↑, ↗, →, ↘, ↓, ↙ 이다. 이동을 명령하면 다음이 순서대로 진행된다.
3+
4+
모든 구름이 di 방향으로 si칸 이동한다.
5+
각 구름에서 비가 내려 구름이 있는 칸의 바구니에 저장된 물의 양이 1 증가한다.
6+
구름이 모두 사라진다.
7+
2에서 물이 증가한 칸 (r, c)에 물복사버그 마법을 시전한다. 물복사버그 마법을 사용하면, 대각선 방향으로 거리가 1인 칸에 물이 있는 바구니의 수만큼 (r, c)에 있는 바구니의 물이 양이 증가한다.
8+
이때는 이동과 다르게 경계를 넘어가는 칸은 대각선 방향으로 거리가 1인 칸이 아니다.
9+
예를 들어, (N, 2)에서 인접한 대각선 칸은 (N-1, 1), (N-1, 3)이고, (N, N)에서 인접한 대각선 칸은 (N-1, N-1)뿐이다.
10+
바구니에 저장된 물의 양이 2 이상인 모든 칸에 구름이 생기고, 물의 양이 2 줄어든다. 이때 구름이 생기는 칸은 3에서 구름이 사라진 칸이 아니어야 한다.
11+
'''
12+
13+
from collections import deque
14+
15+
def copyWater(arr, cloudLoc):
16+
global N
17+
18+
# 대각선 방향의 dx와 dy설정
19+
dx = [-1, -1, 1, 1]
20+
dy = [-1, 1, -1, 1]
21+
22+
for loc in cloudLoc:
23+
increment = 0
24+
locX, locY = loc
25+
26+
for i in range(4):
27+
row = locX + dx[i]
28+
col = locY + dy[i]
29+
30+
if 0 <= row < N and 0 <= col < N and arr[row][col] > 0:
31+
increment += 1
32+
33+
arr[locX][locY] += increment
34+
35+
36+
def moveCloudDropRain(arr, d, s, index, cloudLoc):
37+
# 8가지 이동 경우의 수 설정 (d는 1부터 시작하므로 0-index로 맞춤)
38+
dx = [0, -1, -1, -1, 0, 1, 1, 1]
39+
dy = [-1, -1, 0, 1, 1, 1, 0, -1]
40+
41+
newCloudLoc = deque()
42+
43+
# 각 구름마다 이동
44+
for loc in cloudLoc:
45+
locX, locY = loc
46+
47+
locX = (locX + dx[d[index] - 1] * s[index]) % N
48+
locY = (locY + dy[d[index] - 1] * s[index]) % N
49+
50+
# 새로운 구름 위치 저장
51+
newCloudLoc.append((locX, locY))
52+
53+
# 이동한 구름 위치에 비 내림
54+
arr[locX][locY] += 1
55+
56+
cloudLoc.clear()
57+
cloudLoc.extend(newCloudLoc)
58+
59+
60+
# 비 바라기 수행. 비구름을 생성하고 M번만큼 구름을 이동시켜 비를 내린다.
61+
def makeRain(arr, d, s):
62+
global N, M
63+
64+
# 구름 위치 초기화
65+
initialCloudLocation = [(N - 1, 0), (N - 1, 1), (N - 2, 0), (N - 2, 1)]
66+
cloudLoc = deque(initialCloudLocation)
67+
68+
# 구름이 사라진 위치 저장
69+
disappearedCloudLoc = set()
70+
71+
for i in range(M):
72+
# 구름 이동 & 비내리기 함수
73+
moveCloudDropRain(arr, d, s, i, cloudLoc)
74+
75+
# 물 복사 함수
76+
copyWater(arr, cloudLoc)
77+
78+
# 구름이 사라진 위치 기록
79+
disappearedCloudLoc = set(cloudLoc)
80+
81+
# 새로운 구름 위치를 결정
82+
newCloudLoc = deque()
83+
for r in range(N):
84+
for c in range(N):
85+
# 2 이상의 물이 있고, 사라진 구름 위치가 아닌 경우에만 구름 생성
86+
if arr[r][c] >= 2 and (r, c) not in disappearedCloudLoc:
87+
newCloudLoc.append((r, c))
88+
arr[r][c] -= 2 # 물의 양 2 감소
89+
90+
cloudLoc = newCloudLoc
91+
92+
93+
N, M = map(int, input().split())
94+
arr = []
95+
d, s = [], []
96+
97+
# 초기 물의 양 저장
98+
for _ in range(N):
99+
arr.append(list(map(int, input().split())))
100+
101+
# M개의 이동 명령 저장
102+
for _ in range(M):
103+
temp = input().split()
104+
d.append(int(temp[0]))
105+
s.append(int(temp[1]))
106+
107+
# 비 바라기 수행
108+
makeRain(arr, d, s)
109+
total_sum = sum(sum(row) for row in arr)
110+
print(total_sum)

0 commit comments

Comments
 (0)