|
| 1 | +# 백준 21610번: 마법사 상어와 비바라기 (2회차) |
| 2 | + |
| 3 | +from collections import deque |
| 4 | +import sys |
| 5 | + |
| 6 | +input = sys.stdin.readline |
| 7 | + |
| 8 | +# N <= 50 |
| 9 | +# M <= 10^2 |
| 10 | +N, M = map(int, input().rstrip().split()) |
| 11 | +maps = [list(map(int, input().rstrip().split())) for _ in range(N)] |
| 12 | +queries = [list(map(int, input().rstrip().split())) for _ in range(M)] |
| 13 | + |
| 14 | +# 시간복잡도 계산 |
| 15 | +# 1. 모든 구름이 이동 -> O(N^2) ~= 10^3 |
| 16 | +# 2. 각 구름에서 비가 내려 물이 증가 -> O(N^2) ~= 10^3 |
| 17 | +# 3. 물복사버그 마법 시전 -> O(N^2) ~= 10^3 |
| 18 | +# 3. 위 모든 과정을 10^2번 반복 |
| 19 | + |
| 20 | +moves = { |
| 21 | + 1: [0, -1], |
| 22 | + 2: [-1, -1], |
| 23 | + 3: [-1, 0], |
| 24 | + 4: [-1, 1], |
| 25 | + 5: [0, 1], |
| 26 | + 6: [1, 1], |
| 27 | + 7: [1, 0], |
| 28 | + 8: [1, -1], |
| 29 | +} |
| 30 | + |
| 31 | +clouds = deque() |
| 32 | +clouds.append((N - 2, 0)) |
| 33 | +clouds.append((N - 2, 1)) |
| 34 | +clouds.append((N - 1, 0)) |
| 35 | +clouds.append((N - 1, 1)) |
| 36 | + |
| 37 | +def is_in_board(r, c): |
| 38 | + return 0 <= r < N and 0 <= c < N |
| 39 | + |
| 40 | +def print_board(): |
| 41 | + print('-----------') |
| 42 | + for row in maps: |
| 43 | + print(row) |
| 44 | + |
| 45 | +def clouds_move(di, si): |
| 46 | + prev_clouds = [] |
| 47 | + increased_buckets = [] |
| 48 | + |
| 49 | + # 모든 구름이 di 방향으로 si만큼 이동 |
| 50 | + while clouds: |
| 51 | + r, c = clouds.popleft() |
| 52 | + dr, dc = moves[di] |
| 53 | + new_r, new_c = (r + dr * si + N * 2) % N, (c + dc * si + N * 2) % N |
| 54 | + # 각 구름에서 비가 내려 바구니의 물 1 증가 |
| 55 | + maps[new_r][new_c] += 1 |
| 56 | + increased_buckets.append((new_r, new_c)) |
| 57 | + # 구름이 모두 사라짐 |
| 58 | + prev_clouds.append((new_r, new_c)) |
| 59 | + |
| 60 | + return prev_clouds, increased_buckets |
| 61 | + |
| 62 | +def water_duplication(buckets): |
| 63 | + # 대각선 방향으로 거리가 1인 물이 있는 바구니 수만큼 물 증가 |
| 64 | + for r, c in buckets: |
| 65 | + cnt = 0 |
| 66 | + for direction in [2, 4, 6, 8]: |
| 67 | + dr, dc = moves[direction] |
| 68 | + if is_in_board(r + dr, c + dc) and maps[r + dr][c + dc]: |
| 69 | + cnt += 1 |
| 70 | + maps[r][c] += cnt |
| 71 | + |
| 72 | +def generate_new_clouds(prev_clouds): |
| 73 | + prev_clouds = set(prev_clouds) |
| 74 | + for r in range(N): |
| 75 | + for c in range(N): |
| 76 | + # 바구니에 저장된 물의 양이 2 이상인 모든 칸에 구름이 생김 |
| 77 | + if maps[r][c] >= 2 and (r, c) not in prev_clouds: |
| 78 | + clouds.append((r, c)) |
| 79 | + # 해당하는 칸의 물이 2씩 줄어듦 |
| 80 | + maps[r][c] -= 2 |
| 81 | + |
| 82 | +# print_board() |
| 83 | +for di, si in queries: |
| 84 | + # print((di, si)) |
| 85 | + prev_clouds, buckets = clouds_move(di, si) |
| 86 | + # print_board() |
| 87 | + water_duplication(buckets) |
| 88 | + # print_board() |
| 89 | + generate_new_clouds(prev_clouds) |
| 90 | + # print_board() |
| 91 | + # print() |
| 92 | + |
| 93 | +print(sum([sum(row) for row in maps])) |
0 commit comments