|
| 1 | +# 백준 17143번: 낚시왕 (2회차) |
| 2 | + |
| 3 | +from collections import deque |
| 4 | +import sys |
| 5 | + |
| 6 | +input = sys.stdin.readline |
| 7 | + |
| 8 | +# R, C <= 10^2 |
| 9 | +R, C, M = map(int, input().rstrip().split()) |
| 10 | +maps = [[0 for _ in range(C)] for _ in range(R)] |
| 11 | + |
| 12 | +sharks = {} |
| 13 | +for _ in range(M): |
| 14 | + r, c, speed, direction, size = map(int, input().rstrip().split()) |
| 15 | + maps[r - 1][c - 1] = size |
| 16 | + if direction in [1, 2]: |
| 17 | + sharks[size] = (direction, speed % (2 * (R - 1))) |
| 18 | + else: |
| 19 | + sharks[size] = (direction, speed % (2 * (C - 1))) |
| 20 | + |
| 21 | +moves = { |
| 22 | + 1: [-1, 0], |
| 23 | + 2: [1, 0], |
| 24 | + 3: [0, 1], |
| 25 | + 4: [0, -1] |
| 26 | +} |
| 27 | + |
| 28 | +opposite = { |
| 29 | + 1: 2, |
| 30 | + 2: 1, |
| 31 | + 3: 4, |
| 32 | + 4: 3 |
| 33 | +} |
| 34 | + |
| 35 | +# 시간복잡도 계산 |
| 36 | +# 1. 낚시왕이 오른쪽으로 한 칸 이동 -> O(1) |
| 37 | +# 2. 열에서 가장 가까운 상어를 잡음 -> O(R) = 10^2 |
| 38 | +# 3. 모든 상어가 이동함 -> O(RC) * O(10^3) = 10^7 |
| 39 | +# 4. 1~3의 과정을 낚시왕이 모든 열만큼 반복 -> O(C) = 10^2 |
| 40 | +# 결론: 그냥은 통과 못 할것 같고, 상어의 이동 시 속력을 나누어 이동하지 않고 바로 처리해 버리면 가능할듯? |
| 41 | +# - 예시로 한 번 방향과 칸을 제자리로 돌아오는 만큼은 MOD를 취해도 된다던지... (2R or 2C) |
| 42 | +# 요구사항 구현 |
| 43 | +# 1. 상어는 각각 유니크한 크기를 가지므로, 해시맵으로 관리해도 좋을 듯 |
| 44 | +# 2. 각 상어의 이동 사이에는 공간을 비워 주고, 잠시 큐에 넣어서 다시 재분배하는 방식으로 구현하면 자연스러울듯 |
| 45 | + |
| 46 | +def print_board(): |
| 47 | + for r in range(R): |
| 48 | + for c in range(C): |
| 49 | + if not maps[r][c]: print('.', end=' ') |
| 50 | + else: print(maps[r][c], end=' ') |
| 51 | + print() |
| 52 | + |
| 53 | +def is_in_board(r, c): |
| 54 | + return 0 <= r < R and 0 <= c < C |
| 55 | + |
| 56 | +def sharks_move(): |
| 57 | + q = deque() |
| 58 | + |
| 59 | + for r in range(R): |
| 60 | + for c in range(C): |
| 61 | + if maps[r][c]: |
| 62 | + q.append((r, c, maps[r][c])) |
| 63 | + maps[r][c] = 0 |
| 64 | + |
| 65 | + while q: |
| 66 | + r, c, size = q.popleft() |
| 67 | + direction, speed = sharks[size] |
| 68 | + dr, dc = moves[direction] |
| 69 | + |
| 70 | + for _ in range(speed): |
| 71 | + new_r, new_c = r + dr, c + dc |
| 72 | + if not is_in_board(new_r, new_c): |
| 73 | + direction = opposite[direction] |
| 74 | + dr, dc = moves[direction] |
| 75 | + new_r, new_c = r + dr, c + dc |
| 76 | + |
| 77 | + r, c = new_r, new_c |
| 78 | + |
| 79 | + # 더 큰 상어가 이미 위치해 있는 경우 |
| 80 | + if maps[r][c] and maps[r][c] > size: |
| 81 | + del sharks[size] |
| 82 | + continue |
| 83 | + |
| 84 | + maps[r][c] = size |
| 85 | + sharks[size] = (direction, speed) |
| 86 | + |
| 87 | +fisher_c = -1 |
| 88 | +answer = 0 |
| 89 | + |
| 90 | +# print_board() |
| 91 | +# print() |
| 92 | + |
| 93 | +while fisher_c < C - 1: |
| 94 | + # 낚시왕이 오른쪽으로 한 칸 이동 |
| 95 | + fisher_c += 1 |
| 96 | + # print(f'fisher is in column {fisher_c}') |
| 97 | + |
| 98 | + # 열에서 가장 가까운 상어를 잡음 |
| 99 | + for r in range(R): |
| 100 | + if maps[r][fisher_c]: |
| 101 | + del sharks[maps[r][fisher_c]] |
| 102 | + answer += maps[r][fisher_c] |
| 103 | + maps[r][fisher_c] = 0 |
| 104 | + break |
| 105 | + |
| 106 | + # 모든 상어가 이동함 |
| 107 | + sharks_move() |
| 108 | + |
| 109 | + # print_board() |
| 110 | + # print(f'answer: {answer}') |
| 111 | + # print() |
| 112 | + |
| 113 | +print(answer) |
0 commit comments