Skip to content

Commit f6482e5

Browse files
committed
[BOJ] 20057 마법사 상어와 토네이도 (G3)
1 parent e811d06 commit f6482e5

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

최어진/9주차/260223.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# 백준 20057번: 마법사 상어와 토네이도 (2회차)
2+
3+
import sys
4+
5+
input = sys.stdin.readline
6+
7+
# N <= 499
8+
N = int(input())
9+
sands = [list(map(int, input().rstrip().split())) for _ in range(N)]
10+
11+
# 시간복잡도 자체는...
12+
# 1. 격자의 모든 칸에 대해서 모래 날리기 -> O(N^2) ~= 10^5
13+
# 2. 각 칸마다 날라간 모래 계산 ~= 10
14+
# 결론: 시간복잡도 때문에 문제 생길 것 같지는 않음
15+
16+
moves = [
17+
[0, -1], # <
18+
[1, 0], # v
19+
[0, 1], # >
20+
[-1, 0], # ^
21+
]
22+
23+
splits = [
24+
[
25+
[-1, 0, 0.01],
26+
[1, 0, 0.01],
27+
[-1, -1, 0.07],
28+
[1, -1, 0.07],
29+
[-2, -1, 0.02],
30+
[2, -1, 0.02],
31+
[-1, -2, 0.1],
32+
[1, -2, 0.1],
33+
[0, -3, 0.05],
34+
],
35+
[
36+
[0, -1, 0.01],
37+
[0, 1, 0.01],
38+
[1, -1, 0.07],
39+
[1, 1, 0.07],
40+
[1, -2, 0.02],
41+
[1, 2, 0.02],
42+
[2, -1, 0.1],
43+
[2, 1, 0.1],
44+
[3, 0, 0.05],
45+
],
46+
[
47+
[-1, 0, 0.01],
48+
[1, 0, 0.01],
49+
[-1, 1, 0.07],
50+
[1, 1, 0.07],
51+
[-2, 1, 0.02],
52+
[2, 1, 0.02],
53+
[-1, 2, 0.1],
54+
[1, 2, 0.1],
55+
[0, 3, 0.05],
56+
],
57+
[
58+
[0, -1, 0.01],
59+
[0, 1, 0.01],
60+
[-1, -1, 0.07],
61+
[-1, 1, 0.07],
62+
[-1, -2, 0.02],
63+
[-1, 2, 0.02],
64+
[-2, -1, 0.1],
65+
[-2, 1, 0.1],
66+
[-3, 0, 0.05],
67+
],
68+
]
69+
70+
remains = [
71+
[0, -2],
72+
[2, 0],
73+
[0, 2],
74+
[-2, 0]
75+
]
76+
77+
r, c = N // 2, N // 2
78+
direction = 0
79+
answer = 0
80+
81+
def is_in_board(r, c):
82+
return 0 <= r < N and 0 <= c < N
83+
84+
def print_sands(current_r, current_c):
85+
global answer
86+
for r in range(N):
87+
for c in range(N):
88+
if r == current_r and c == current_c: print('#', end=' ')
89+
elif not sands[r][c]: print('.', end=' ')
90+
else: print(sands[r][c], end=' ')
91+
print()
92+
print(f'answer: {answer}')
93+
print()
94+
95+
def split(r, c, direction):
96+
global answer
97+
# print(f'split(r: {r}, c: {c}), direction: {direction}')
98+
99+
# y칸의 좌표 저장
100+
dr, dc = moves[direction]
101+
yr, yc = r + dr, c + dc
102+
y_sands = sands[yr][yc]
103+
if not y_sands: return
104+
105+
for dr, dc, portion in splits[direction]:
106+
# 이동할 모래의 양 계산, 소수점 아래 버림
107+
z_sands = int(y_sands * portion)
108+
# 모래의 이동
109+
sands[yr][yc] -= z_sands
110+
if is_in_board(r + dr, c + dc):
111+
sands[r + dr][c + dc] += z_sands
112+
else:
113+
answer += z_sands
114+
115+
dr, dc = remains[direction]
116+
ar, ac = r + dr, c + dc
117+
if is_in_board(ar, ac):
118+
sands[ar][ac] += sands[yr][yc]
119+
else:
120+
answer += sands[yr][yc]
121+
sands[yr][yc] = 0
122+
123+
for i in range(1, N):
124+
for _ in range(i):
125+
split(r, c, direction)
126+
# print_sands(r, c)
127+
dr, dc = moves[direction]
128+
r, c = r + dr, c + dc
129+
direction = (direction + 1) % 4
130+
for _ in range(i):
131+
split(r, c, direction)
132+
# print_sands(r, c)
133+
dr, dc = moves[direction]
134+
r, c = r + dr, c + dc
135+
direction = (direction + 1) % 4
136+
for _ in range(i):
137+
split(r, c, direction)
138+
# print_sands(r, c)
139+
dr, dc = moves[direction]
140+
r, c = r + dr, c + dc
141+
direction = (direction + 1) % 4
142+
143+
print(answer)

0 commit comments

Comments
 (0)