문제에 주어진 조건들만 잘 활용하면 쉽게 풀 수 있는 문제였다.
자세한 코드 설명은 코드와 함께 하겠습니다.
from itertools import combinations
import copy
import heapq #개인적으로 heap사용 덕분에 쉽게 푼거 같다.
def bfs(t,sk):#거리에 맞는거 찾기(t = 조합중에 하나,sk=s배열을 deepcopy한것)
hpq = []
for i in range(n):
for j in range(m):
if sk[i][j]==1:#만약에 병사가 있다면
for u in t:#각 사수들로부터 거리를 구해줌
if abs(n-i)+abs(u-j)<=d:#사정거리 안이면 heap에 저장
heapq.heappush(hpq,(abs(n-i)+abs(u-j),j,i,u))
#(사정거리,j,i,사수위치)인 이유 문제 조건이 사정거리가 짧은 곳을 우선으로 하고
#거리가 같을때는 왼쪽을 먼저 쏘라고 했어서 사수위치는 같은 병사를 쏠 수 있기때문.
return hpq
def shot(hpq,s,cont):#죽이기
vist = [False]*(m)#사수의 발사 여부
while hpq:
q,j,i,t = heapq.heappop(hpq)
if not vist[t]:#사수가 안 쐈으면 쏜다.
vist[t]=True#쐈으니 True
if s[i][j]==1:만약에 1이면 아직 병사가 살아있다는 것이니
cont+=1#처치 병사 +1
s[i][j]=0# 이병사는 죽을 수 밖에 없으므로 0으로 바꿔줌
return cont#죽인 병사의 수 return
def move(s):#움직이기
for i in range(n-1,-1,-1):#한칸씩 아래로 내려준다.
for j in range(m):
s[i][j] = s[i-1][j]
def main(i):#코드의 간결화를 위해서 main함수를 만들어줌.
global maxs
cont =0
sk = copy.deepcopy(s)
for _ in range(n):#병사가 0행에 있을 수 있으니 n번 내려주면 남아있는 병사는 없음.
h = bfs(i,sk)
cont = shot(h,sk,cont)
move(sk)
maxs = max(cont,maxs)#최댓값 갱신
n,m,d =map(int,input().split())
s =[list(map(int,input().split())) for i in range(n)]
s.append([0]*m)#move할때 위에 0행을 0으로 채우기 위해 추가해줌
cos = list(combinations([i for i in range(m)],3))#사수를 배치할 수 있는 모든 경우의 수
maxs = -1
for i in cos:
main(i)#main(i)함수 작동해줌으로써 사수의 위치가 i 일때 죽인 병사의 값을 알려줌
print(maxs)
'백준 파이썬 코딩' 카테고리의 다른 글
백준 10971 외판원 순회 2 파이썬 (0) | 2022.08.25 |
---|---|
백준 1541 잃어버린 괄호 파이썬 (0) | 2022.08.24 |
백준 13144 List of Unique Numbers 파이썬 주석 설명 O (0) | 2022.08.20 |
백준 15903 카드 합체 놀이 파이썬 (0) | 2022.08.19 |
백준 11052 카드 구매하기 파이썬 (0) | 2022.08.19 |