In [1]:
1
2
3
4
5
6
7
8
9
10
import sys, random, heapq
sys.path.append("/home/swyoo/algorithm/")
from utils.generator import random2D
from utils.verbose import logging_time
from collections import defaultdict, deque
from copy import deepcopy
from typing import DefaultDict, Deque, Tuple, List
from pprint import pprint
import numpy as np
plot = lambda a: print(np.array(a))
16235. 나무 재테크
In [2]:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def generator():
n = random.randint(1, 10)
m, k = random.randint(1, n ** 2), random.randint(1, 1000)
a = random2D(shape=(n, n), randrange=(1, 100))
data = [(random.randint(0, n - 1), random.randint(0, n - 1), random.randint(1, 10)) for _ in range(m)]
trees = defaultdict(deque)
for x, y, z in data:
trees[(x, y)].append(z)
for pos, ages in trees.items():
trees[pos] = deque(sorted(ages))
ntrs = [[5] * n for _ in range(n)]
return n, m, k, a, trees, ntrs
n, m, k, a, trees, ntrs = generator()
# print(n ,m, k)
# plot(a)
# print(trees)
In [3]:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@logging_time
def solution(a: List[List[int]], trees: DefaultDict[Tuple[int, int], Deque[int]], ntrs: List[List[int]], k: int, show: bool = False):
n = len(a)
delta = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
def spring_summer():
# spring
for (i, j), ages in trees.items():
alives, deads = deque(), 0
for age in ages:
if ntrs[i][j] < age:
deads += (age // 2)
continue
alives.append(age + 1)
ntrs[i][j] -= age
trees[(i, j)] = alives
# summer
ntrs[i][j] += deads
def fall_winter():
# fall
reproduce = []
for (i, j), ages in trees.items():
for age in ages:
if age % 5: continue
for dx, dy in delta:
if 0 <= i + dx < n and 0 <= j + dy < n:
reproduce.append((i + dx, j + dy))
# fall: reproduce
for pos in reproduce:
trees[pos].appendleft(1)
# winter
for i in range(n):
for j in range(n):
ntrs[i][j] += a[i][j]
for _ in range(k):
spring_summer()
if not trees: return 0
fall_winter()
return sum(len(vs) for _, vs in trees.items())
In [4]:
1
2
n, m, k, a, trees, ntrs = generator()
solution(*deepcopy((a, trees, ntrs, k)), show=False, verbose=True)
1
2
WorkingTime[solution]: 0.18120 ms
1
0
Submitted Code
deque 와 reproduce에서 list사용
In [5]:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from collections import defaultdict, deque
from sys import stdin
stdin = open('data/treeinvest.txt')
input = stdin.readline
n, m, k = list(map(int, input().split()))
a = [list(map(int, input().split())) for _ in range(n)]
trees = defaultdict(deque)
for _ in range(m):
x, y, z = list(map(int, input().split()))
trees[(x - 1, y - 1)].append(z)
for pos, ages in trees.items():
trees[pos] = sorted(deque(ages))
ntrs = [[5] * n for _ in range(n)]
delta = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
def solution(a, trees, ntrs, k):
def spring_summer():
# spring
for (i, j), ages in trees.items():
alives, deads = deque(), 0
for age in ages:
if ntrs[i][j] < age:
deads += (age // 2)
continue
alives.append(age + 1)
ntrs[i][j] -= age
trees[(i, j)] = alives
# summer
ntrs[i][j] += deads
def fall_winter():
# fall
reproduce = []
for (i, j), ages in trees.items():
for age in ages:
if age % 5: continue
for dx, dy in delta:
if 0 <= i + dx < n and 0 <= j + dy < n:
reproduce.append((i + dx, j + dy))
# fall: reproduce
for pos in reproduce:
trees[pos].appendleft(1)
# winter
for i in range(n):
for j in range(n):
ntrs[i][j] += a[i][j]
for _ in range(k):
spring_summer()
if not trees: return 0
fall_winter()
return sum(len(vs) for _, vs in trees.items())
print(solution(a, trees, ntrs, k))
1
2
85
Report
시간초과가 뜨는 바람에 많은 시간은 허비했다.
- 처음 시도했던것은 heap을 사용하였는데,
heappush, heappop
에 대한 overhead때문에 효율이 좋지 못했다. deque
를 사용하면, 좀더 효율적으로 어린 나무가 먼저 양분을 먹게 할 수 있다.- 왜냐하면, 봄에 죽은 나무를 제외하고 새로 deque를 만들어 놓고, 가을에
appendleft
를 통해 앞쪽에 어린 나무를 추가해나가면 된다.
- 왜냐하면, 봄에 죽은 나무를 제외하고 새로 deque를 만들어 놓고, 가을에
- dictionary를 사용한
items()
가 매우 느린 iteration을 만드는 것같다.reproduce
를 dictionart에서 list로 바꾸었더니 pypy3에서 통과되었다.
Leave a comment