
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5V4A46AdIDFAWu
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
아이디어
- 일단 조합을 사용해야겠다는 생각이 들었다.
- itertools를 사용하자.
- 완전탐색해서 먼저 첫 번째 일꾼의 꿀을 찾고, 그 구역을 -1로 처리해서 두 번째 일꾼이 -1 부분은 채취하지 못하게 한다.
풀이
from itertools import combinations
# 숫자를 담은 리스트를 넘겨주면 그 숫자들의 모든 조합에서 최대의 꿀 값을 찾아낸다.
def comb(nums):
candi_cnt = 0
for k in range(1, M+1):
aa = list(combinations(nums, k))
for num in aa:
tmp_cnt = 0
if sum(num) > C:
continue
for l in range(k):
tmp_cnt += num[l-1]**2
candi_cnt = max(candi_cnt, tmp_cnt)
return candi_cnt
for tc in range(int(input())):
N, M, C = map(int, input().split())
honey = [list(map(int, input().split())) for _ in range(N)]
# 첫 일꾼의 숫자들을 담을 리스트
rst_nums = []
# 그 부분의 인덱스 번호들
rst_idx = []
# 최대의 꿀 값
rst_cnt = 0
# 먼저 첫 번째 일꾼이 최대의 꿀을 채취한다.
for i in range(N):
for j in range(N-M+1):
tmp_idx = []
tmp_nums = []
tmp_cnt = 0
for m in range(M):
tmp_idx.append((i, j+m))
tmp_nums.append(honey[i][j+m])
if sum(tmp_nums) <= C:
for num in tmp_nums:
tmp_cnt += num**2
elif sum(tmp_nums) > C:
tmp_cnt = comb(tmp_nums)
if rst_cnt < tmp_cnt:
rst_cnt = tmp_cnt
rst_nums = tmp_nums
rst_idx = tmp_idx
# 첫 번째 일꾼이 채취한 부분을 -1로 바꿔준다.
while rst_idx:
r, c = rst_idx.pop()
honey[r][c] = -1
# 두 번째 일꾼
rst2_nums = []
rst2_idx = []
rst2_cnt = 0
# 첫 번째 일꾼이 채취한 방식과 똑같지만, -1영역은 채취를 하지 않는다.
for i in range(N):
for j in range(N - M + 1):
tmp_idx = []
tmp_nums = []
tmp_cnt = 0
for m in range(M):
tmp_idx.append((i, j + m))
tmp_nums.append(honey[i][j + m])
if -1 in tmp_nums:
continue
if sum(tmp_nums) <= C:
for num in tmp_nums:
tmp_cnt += num ** 2
elif sum(tmp_nums) > C:
tmp_cnt = comb(tmp_nums)
if rst2_cnt < tmp_cnt:
rst2_cnt = tmp_cnt
rst2_nums = tmp_nums
rst2_idx = tmp_idx
print(f'#{tc+1}', rst_cnt+rst2_cnt)
후기
- 일단, 코드가 너무 지저분하다. 완전탐색에 탐욕적 기법을 약간 섞은 느낌이다.
- 이 문제의 경우 일꾼이 두 명이라 일일히 일꾼 1 -> 일꾼 2로 작성했지만,
- 일꾼이 M명이라면..? 함수를 만들어 반복할 수 있게 해주거나, while을 통해 같은 작업을 하는 식으로 작성해볼 수도 있겠지만, pass 했으니 pass 하기로 하자..
'SWEA' 카테고리의 다른 글
SWEA 1767 프로세서 연결하기 (파이썬) (1) | 2022.10.13 |
---|---|
SWEA 4008 숫자 만들기 (파이썬) (0) | 2022.09.30 |
SWEA 1952 수영장 (파이썬) (0) | 2022.09.30 |
SWEA 1251 하나로 (파이썬) (1) | 2022.09.30 |
SWEA 1249 보급로 (파이썬) (1) | 2022.09.30 |