[白俊]17135番城防御


質問リンク


https://www.acmicpc.net/problem/17135

問題の説明

  • 敵が城壁から降りてきた
  • 弓矢手たちが敵を撃退する
  • アーチェリー3人を配置し、掴める相手の最低価格
  • を獲得する.

    に答える

  • の組み合わせのすべての状況を探す
  • すべての場合
  • BFS、アーチェリーの手を押して最も近い左側の敵
  • を探します
  • ボードから削除する、
  • カウントする.
  • 敵は1格下がった(城壁に登った)
  • 城壁の果てまで繰り返します

    BFSの実装

  • 左、上、右の順に3方向のみ追加
  • 距離を
  • ノードに格納、交差点以上で空の
  • に戻る.
  • 交差点以内の敵がいなければ、空
  • に戻る

    予測時間の複雑さ

  • 低音砲:15組3
  • すべての行の繰り返し:O(N)
  • BFS : O(N x M + 4 x (N x M)) = O(N x M)
  • に感銘を与える

  • 初めて弓矢手たちが同時に敵の言葉に当たったのを見て、少し迷った.
  • コード#コード#

    from itertools import combinations
    from collections import deque
    
    
    def init():
        import sys
        ipt = sys.stdin.readline
        h, w, d = map(int, ipt().split())
        origin_board = [list(map(int, ipt().split())) for _ in range(h)]
        dy = [0, -1, 0]
        dx = [-1, 0, 1]
        return w, h, origin_board, -1, dy, dx, d
    
    
    def bfs(start):
        sy, sx = start
        visited = [[False] * w for _ in range(h)]
        visited[sy][sx] = True
        q = deque()
        q.append((sy, sx, 1))
        while q:
            cy, cx, cd = q.popleft()
            if cd > d:
                return
            if board[cy][cx] == 1:
                return (cy, cx)
            for i in range(3):
                ny = cy + dy[i]
                nx = cx + dx[i]
                if 0 <= ny < h and 0 <= nx < w:
                    if not visited[ny][nx]:
                        visited[ny][nx] = True
                        q.append((ny, nx, cd+1))
    
    
    w, h, origin_board, ans, dy, dx, d = init()
    for x1, x2, x3 in combinations(range(w), 3):
        board = [origin_board[i][:] for i in range(h)]
        count = 0
        floor = h
        while floor:
            enemy_list = [
                bfs((floor-1, x1)),
                bfs((floor-1, x2)),
                bfs((floor-1, x3)),
            ]
            for enemy in enemy_list:
                if enemy:
                    ey, ex = enemy
                    if board[ey][ex]:
                        board[ey][ex] = 0
                        count += 1
            floor -= 1
        ans = max(ans, count)
    print(ans)