카테고리 없음

[BOJ] 17135 캐슬 디펜스 - Python

징석 2021. 8. 12. 08:12
728x90

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

 

17135번: 캐슬 디펜스

첫째 줄에 격자판 행의 수 N, 열의 수 M, 궁수의 공격 거리 제한 D가 주어진다. 둘째 줄부터 N개의 줄에는 격자판의 상태가 주어진다. 0은 빈 칸, 1은 적이 있는 칸이다.

www.acmicpc.net

BFS  + 조합 + 우선순위 정렬 을 사요애야하는 조금 복잡한 문제다.

어느 적부터 쏴야 할지를 선택해야 하고..

궁수를 배치하는 건 조합을 사용하고

적이 어딨는지 탐색하는 부분은 BFS

 

 

 

from itertools import combinations
import heapq

# 위, 오른, 왼 방향
dx = [-1, 0, 0]
dy = [0, 1, -1]

#입력
N, M, D= map(int,input().split())
arra = [[0]*M for _ in range(N)]
for i in range(N):
    line = list(map(int,input().split()))
    for j in range(M):
        arra[i][j] = line[j]

bower = [i for i in range(M)]
arra.append(bower)


def bfs(line, bow, arr):
    global D
    res = [[] for _ in range(32)]
    visit = [[0]*M for _ in range(N+1)]
    q = []
    visit[line][bow] = True
    heapq.heappush(q, (0, bow, line))
    while q:
        front = heapq.heappop(q)
        dist = front[0]
        x = front[2]
        y = front[1]
        if arr[x][y] == 1:
            heapq.heappush(res[dist], (y,x))
        for i in range(3):
            xx = x + dx[i]
            yy = y + dy[i]
            if 0 <= xx <N and 0<= yy < M and visit[xx][yy] == False:
                heapq.heappush(q, (dist+1, yy, xx))
                visit[xx][yy] = True
    return res
maxval = 0
aaa = 0
tup = set()
for p in combinations(bower,3):
    bow_arr = [0]*M
    for i in p:
        bow_arr[i] = 2
    bow = []
    cnt = 0
    arra[N] = bow_arr
    for i in range(len(bow_arr)):
        if bow_arr[i] == 2:
            bow.append(i)
    one = bfs(N, bow[0], arra)
    two = bfs(N, bow[1], arra)
    three = bfs(N, bow[2], arra)
    tar = set()
    lines =set()
    for j in range(1, N+1):
        tempset = set()
        visit = [0]*3
        for i in range(j, j+D):
            if len(one[i]) > 0 and visit[0] == False:
                while True:
                    if not one[i]:
                        break
                    o = heapq.heappop(one[i])
                    if o[1] in lines:
                        continue
                    if o not in tar:
                        tempset.add(o)
                        visit[0] = True
                        break
            if len(two[i]) > 0 and visit[1] == False:
                while True:
                    if not two[i]:
                        break
                    o = heapq.heappop(two[i])
                    if o[1] in lines:
                        continue
                    if o not in tar:
                        tempset.add(o)
                        visit[1] = True
                        break
            if len(three[i]) > 0 and visit[2] == False:
                while True:
                    if not three[i]:
                        break
                    o = heapq.heappop(three[i])

                    if o[1] in lines:
                        continue
                    if o not in tar :
                        visit[2] = True
                        tempset.add(o)
                        break
        lines.add(N-j)
        for temp in tempset:
            tar.add(temp)
    cnt = len(tar)
    if maxval < cnt:
        maxval = cnt

print(maxval)