[SWEA][D4][#02117] 홈 방범 서비스
작성:    
업데이트:
카테고리: SWEA D4
태그: ProblemSolving, SWEA D4, SWEA PS
출처
학습용 포스트입니다. 본 포스트가 문제가 될 시 수정 또는 삭제하겠습니다.
문제
문제 생략
My Sol
def main(L):
global maxV
for k in range(L, 0, -1):
for i in range(N):
for j in range(N):
subMain(k, i, j)
if maxV:
return maxV
return 1
def subMain(L, ni, nj):
nowCnt = 0
for ci in range(ni-L, ni+L+1):
for cj in range(nj-L, nj+L+1):
if not (0<=ci<N and 0<=cj<N): continue
if not mat[ci][cj]: continue
if L < abs(ni-ci) + abs(nj-cj): continue
nowCnt += 1
if nowCnt*M >= costLst[L]:
global maxV
maxV = max(maxV, nowCnt)
# costLst
costLst = [0]*40
costLst[0] = 1
i = 1
while i < 40:
costLst[i] = costLst[i-1]+i*4
i += 1
T = int(input())
for tc in range(1, T+1):
N, M = map(int, input().split())
mat = [list(map(int, input().split())) for _ in range(N)]
# 집의 개수 homeCnt
homeCnt = 0
for i in range(N):
for j in range(N):
if mat[i][j]:
homeCnt += 1
# 최대 크기 L
total = M*homeCnt
L = 0
while costLst[L] < total:
L += 1
maxV = 0
print(f'#{tc} {main(L)}')
처음에 중앙으로부터 가장 멀리 갈 수 있는 길이인 L을 인덱스로 하는 costLst를 만들어, while문으로 L에 따른 범위의 비용을 계산해주었다. 그리고 전체 집의 개수를 세어 M을 곱한 값보다 넓이가 클 수 없기 때문에 while문을 이용해 가장 큰 넓이를 허용하는 L을 구하였다.
이후 main() 함수를 실행해주는데, 이 함수는 L부터 시작해서 0까지, 2차원 배열의 각 칸을 돌며 주변 범위에 대해 손해를 보는지, 보지 않는지를 체크하는 함수이다. 이 함수 내의 L부터 시작하는 k마다 전역변수 maxV가 0이 아닌지를 체크하는데, 만약 어떤 k에서 면적에 비해 집의 개수가 충분해서 손해를 보지 않는다고 판단되면 집의 개수를 구해 maxV와 비교해 더 큰 값을 maxV로 갱신한다. 이는 k가 같은 경우, 모든 2차원 배열을 돌면서 가장 집을 많이 포함할 수 있는 좌표점의 집의 개수를 최대로 갱신하기 위함이다.
그 각각의 기준점마다 범위 내의 집을 체크하고, 손해를 보는지를 체크하는 함수가 subMain() 함수이다. main()함수의 각 k, i, j마다 호출되는 이 함수의 주요 역할은 범위 내의 집의 개수를 세는 것이다. 주목해야할 점은 현재 기준점이 ni, nj일 때 ni-L부터 ni+L까지, nj-L부터 nj+L까지의 범위 내에 마름모 범위가 확실히 들어가는 것이다. 때문에 이 범위 내의 각각의 좌표를 ci, cj로 두고 아래의 사항을 확인한다.
- ci, cj가 0부터 N-1의 인덱스 범위를 넘지 않는지
- mat[ci][cj]가 0이 아닌, 1로서 집이 맞는지
- ni와 ci, nj와 cj의 합, 즉 거리가 L보다 크지는 않는지
위의 3가지를 모두 만족한다면 마름모 범위 내의 집이므로 nowCnt를 1 올려준다. 이렇게 모든 칸을 조회하여 nowCnt를 구하면, 이 개수와 집당 금액인 M을 곱한 값이 현재 L에 대한 범위 비용 costlst[L] 보다 크거나 같다면 maxV를 nowCnt와의 비교로 더 큰 값으로 갱신해주는 것이다.
아쉬운 점은 마름모의 크기에 비해 조사하는 범위는 2배이기 때문에 배열이 커질수록 불필요한 연산이 많아지지만, 코드가 직관적이기 때문에 위와 같이 작성하였다.
결과
PASS
댓글남기기