[Python] [백준 #1026] zip으로 리스트끼리 연산하기
import sys
input = sys.stdin.readline
N = int(input())
A = []
B = []
A = sorted(list(map(int, input().split())))
B = sorted(list(map(int, input().split())))
B.reverse()
result = [i*j for i, j in zip(A, B)]
total_min = sum(result)
print(total_min)
내가 작성한 코드는 이렇다..
(잘 못하니까 참고는 다른 분꺼 .. 하시길 ..)
내가 생각한 로직은 이렇다.
두 번째, 세 번째 줄에 각각 정수 배열 A와 B의 값이 스페이스로 구분되어 입력되면
이를 받아 리스트에 저장한다.
split()을 이용해서 input()을 스페이스를 기준으로 값을 받아
map으로 각 값들을 정수로 바꾸고
list 안에 넣는다.
S의 값을 가장 작게 만들기 위해 A의 수를 재배열해야 하고, 이때 B는 재배열하면 안된다.
예제를 통해 A의 수를 재배열 해보자.
5
1 1 1 6 0
2 7 8 3 1
곱의 전체 합이 최소가 되어야 하므로
1 1 0 1 6
2 7 8 3 1
으로 A의 수를 재배열,
총 합은 1*2 + 1*7 + 0*8 + 1*3 + 6*1 으로 18이다.
매치된 숫자들을 잘 보면
규칙을 찾을 수 있다.
A에서 작은 값은 B에서 큰 값으로 매치된다.
따라서 나는
A를 오름차순 정렬, B를 내림차순 정렬하고 곱하기로 했다.
정렬을 한 뒤 A와 B 리스트의 요소를 순서대로 각각 곱해주어야 한다.
이때 사용한 것이 바로 zip이다.
내장함수 zip
zip은 여러 배열을 튜플로 묶어주는 연산을 해준다.
내장함수이므로 따로 import는 필요 없다.
a = [1, 2, 3, 4, 5]
b = [6, 7, 8, 9, 10]
print([i for i in zip(a, b)]
#[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
a, b의 값을 튜플로 묶어준 것을 확인할 수 있다.
두 값에 대한 연산을 해보자
a = [1, 2, 3, 4, 5]
b = [6, 7, 8, 9, 10]
print([i*j for i, j in zip(a, b)]
#[6, 14, 24, 36, 50]
이 방법을 이용해서
문제의 A, B의 곱을 구해주면 되겠다!
오름차순 정렬한 A와 내림차순 정렬한 B의 요소들을 곱해서
result에 배열로 저장하고
sum(result)를 통해 각 요소의 전체 합을 구하면 된다.
해결 ~!
추가적으로 찾아보면서 알게 된 내용
zip() 함수는 iterable(반복 가능한) 자료형의 개수가 동일할 때 사용할 수 있다.
여러 개의 iterable 객체를 인자로 받고, 각 객체가 담고 있는 원소를 튜플의 형태로
차례로 접근할 수 있는 반복자(iterator)를 반환한다.
zip() 함수를 2차원 배열에 사용하면 쉽게 row, column을 뒤집을 수 있다.
위에서 언급했듯, 배열 크기가 같아야 하므로 N*N 배열에 적용된다.
arrays = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flip_arrays = list(map(list, zip(*arrays)))
print(arrays)
# [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(flip_arrays)
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
for item in zip(*arrays):
print(item)
# (1, 4, 7)
# (2, 5, 8)
# (3, 6, 9)