Skip to content

Commit 0579993

Browse files
committed
마법사 상어와 복제
1 parent cb3fcc2 commit 0579993

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

baekjoon/23290.py

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# https://www.acmicpc.net/problem/23290
2+
3+
from collections import defaultdict, namedtuple
4+
from copy import deepcopy
5+
6+
NUM_ROWS = 4
7+
NUM_COLUMNS = 4
8+
9+
FISH_DR = [0, -1, -1, -1, 0, 1, 1, 1]
10+
FISH_DC = [-1, -1, 0, 1, 1, 1, 0, -1]
11+
NUM_FISH_DIRS = 8
12+
13+
SHARK_DR = [-1, 0, 1, 0]
14+
SHARK_DC = [0, -1, 0, 1]
15+
NUM_SHARK_DIRS = 4
16+
17+
Location = namedtuple("Location", ["r", "c"])
18+
19+
20+
def is_valid(r: int, c: int) -> bool:
21+
return 0 <= r < NUM_ROWS and 0 <= c < NUM_COLUMNS
22+
23+
24+
def count_fish(fish_locs: dict[Location, list[int]]) -> int:
25+
return sum(len(directions) for directions in fish_locs.values())
26+
27+
28+
def main() -> None:
29+
fish_locs, shark_loc, num_castings = stdin_bj23290()
30+
scent = {}
31+
32+
for _ in range(num_castings):
33+
copied_fish_locs = deepcopy(fish_locs)
34+
fish_locs = move_fish(fish_locs, scent, shark_loc)
35+
36+
for loc in list(scent.keys()):
37+
scent[loc] -= 1
38+
if not scent[loc]:
39+
scent.pop(loc)
40+
41+
shark_loc, fish_locs, scent = move_shark(shark_loc, fish_locs, scent)
42+
43+
for loc, directions in copied_fish_locs.items():
44+
fish_locs[loc].extend(directions)
45+
46+
print(count_fish(fish_locs))
47+
48+
49+
def stdin_bj23290() -> tuple[dict[Location, list[int]], Location, int]:
50+
num_fish, num_castings = map(int, input().split())
51+
52+
def n_to_idx(n: str) -> int:
53+
return int(n) - 1
54+
55+
fish_locs = defaultdict(list)
56+
for _ in range(num_fish):
57+
*loc, d = map(n_to_idx, input().split())
58+
fish_locs[Location(*loc)].append(d)
59+
60+
shark_loc = Location(*map(n_to_idx, input().split()))
61+
62+
return fish_locs, shark_loc, num_castings
63+
64+
65+
def move_fish(
66+
fish_locs: dict[Location, list[int]], scent: dict[Location, int], shark_loc: Location
67+
) -> dict[Location, list[int]]:
68+
next_fish_locs = defaultdict(list)
69+
70+
def forward(r: int, c: int, *, d: int) -> Location:
71+
return Location(r + FISH_DR[d], c + FISH_DC[d])
72+
73+
for loc, directions in fish_locs.items():
74+
next_loc = loc
75+
for d in directions:
76+
for _ in range(NUM_FISH_DIRS):
77+
forward_loc = forward(*loc, d=d)
78+
if (
79+
is_valid(*forward_loc)
80+
and forward_loc not in scent
81+
and forward_loc != shark_loc
82+
):
83+
next_loc = forward_loc
84+
break
85+
86+
d = (d - 1) % NUM_FISH_DIRS
87+
88+
next_fish_locs[next_loc].append(d)
89+
90+
return next_fish_locs
91+
92+
93+
def move_shark(
94+
shark_loc: Location, fish_locs: dict[Location, list[int]], scent: dict[Location, int]
95+
) -> tuple[Location, dict[Location, list[int]], dict[Location, int]]:
96+
def dfs(
97+
r: int,
98+
c: int,
99+
*,
100+
route: list[Location],
101+
num_excluded: int,
102+
remaining: int
103+
) -> tuple[int, list[Location]]:
104+
if not remaining:
105+
return num_excluded, route
106+
107+
max_excluded = None
108+
max_route = None
109+
for loc in [Location(r + SHARK_DR[d], c + SHARK_DC[d]) for d in range(NUM_SHARK_DIRS)]:
110+
if not is_valid(*loc):
111+
continue
112+
113+
next_excluded = num_excluded
114+
if loc in fish_locs and loc not in route:
115+
next_excluded += len(fish_locs[loc])
116+
117+
total_excluded, total_route = dfs(
118+
*loc,
119+
route=route + [loc],
120+
num_excluded=next_excluded,
121+
remaining=remaining - 1
122+
)
123+
124+
if max_excluded is None or total_excluded > max_excluded:
125+
max_excluded = total_excluded
126+
max_route = total_route
127+
128+
return max_excluded, max_route
129+
130+
num_excluded, route = dfs(
131+
*shark_loc,
132+
route=[],
133+
num_excluded=0,
134+
remaining=3
135+
)
136+
137+
for loc in route:
138+
if loc not in fish_locs:
139+
continue
140+
141+
fish_locs.pop(loc)
142+
scent[loc] = 2
143+
144+
shark_loc = route[-1]
145+
146+
return shark_loc, fish_locs, scent
147+
148+
149+
if __name__ == "__main__":
150+
main()

0 commit comments

Comments
 (0)