출처 : SW Expert Academy
식재료 i를 식재료 j와 같이 요리하게 되면 발생하는 시너지 Sij의 정보가 주어지고, 가지고 있는 식재료를 이용해 A음식과 B음식을 만들 때, 두 음식 간의 맛의 차이가 최소가 되는 경우를 찾고 그 최솟값을 정답으로 출력하는 프로그램을 작성하라.
[입력]
T : 총 테스트 케이스의 개수
N : 식재료의 수
다음 N개의 줄에는 N * N개의 시너지 Sij값들이 주어진다.
[출력]
#과 두 음식 간의 맛의 차이가 최소가 되도록 A음식과 B음식을 만들었을 때 그 차이 값
# pass!
import sys
sys.stdin = open('input.txt')
def food (first , second):
global min_sub
a = 0
b = 0
# 재료 갯수만큼 반복 더함
for i in range(len(first)):
# Sij + Sji 부분
a += (arr[first[i][0]][first[i][1]] + arr[first[i][1]][first[i][0]])
b += (arr[second[i][0]][second[i][1]] + arr[second[i][1]][second[i][0]])
if min_sub > abs(a-b):
min_sub = abs(a-b)
# 조합1 = 총 재료를 반으로 나누는 조합
def com(n, r, s, k):
if k == r:
comb_list.append(comb[:])
return
else:
for i in range(s, n-r+k+1):
comb[k] = i
com(n, r, i+1, k+1)
# 조합2 = 한사람의 재료를 2개씩 조합 ex)[0,1,2] -> [[0,1],[0,2],[1,2]]
def comb2(arr):
result = []
for i in range(len(arr)):
for j in arr[i + 1:]:
result.append((arr[i], j))
return result
T = int(input())
for tc in range(1,T+1):
N = int(input())
arr = [list(map(int, input().split())) for _ in range(N)]
comb = [0] * (N//2)
min_sub = 999999
comb_list=[]
com(N, N//2, 0, 0)
first = comb_list[:len(comb_list)//2]
second = comb_list[:len(comb_list)//2-1:-1]
for i in range(len(first)):
food(comb2(first[i]), comb2(second[i]))
print("#{} {}".format(tc, min_sub))
comb_list.append(comb) ------<1>
comb_list.append(comb[:])----<2>
처음 <1>로 작성했었는데 결과가 예를 들어,
[0,1,2,3,4,5]의 3개의 조합을 구하는 comb1에서
[[3,4,5],[3,4,5] ...[3,4,5]]로 나온다.
이게 comb를 append 하는건데 함수가 진행될때마다 comb는 바뀌고
저장되어있는 메모리위치의 값을 저장하는 거라서
마지막 저장인 [3,4,5]가 최종적으로 나오게 된다
이거 해결하려면
슬라이싱!!
<2>처럼 작성해야 한다!!