두 배열의 합 - 2143
Category: Baekjoon
Tags: binarysearch sort algorithm
문제의 입력은 다음과 같이 주어졌다고 할 때,
$T=5$
$A = {{1, 3, 1, 2}}$
$B = {{1, 3, 2}}$
($A$의 subset의 합) + ($B$의 subset의 합) = $T$가 되도록 하는 경우의 수를 구하는 문제
시행 착오 1 - 메모리 초과 🥲
첫번째로 접근한 방식은
- A에서 가능한 subset의 합들을 A 배열에 추가
- B에서 가능한 subset의 합들을 B 배열에 추가
- (A의 element) + (B의 element) = T가 되는 경우의 수 찾기
T = int(input())
n = int(input())
A = list(map(int, input().split()))
m = int(input())
B = list(map(int, input().split()))
for i in range(n-1):
temp = A[i]
while temp < T: # 이 부분 문제 발생 -> 마이너스 값 가능성
temp += A[i+1]
A.append(temp)
for i in range(m-1):
temp = B[i]
while temp < T:
temp += B[i+1]
B.append(temp)
res = 0
for num in A: # A 원소 + B 원소 = T가 되는 경우의 수 찾기
for num2 in B: # 이 부분 최적화 필요 -> 이진 탐색
if num2 == (T - num):
res += 1
print(res)
잘 안돌아가서 스터디 팀원 분에게 피드백을 요청했는데 접근 방식은 비슷하게 맞았지만 구현 방식에서 잘못된 부분이 많았다.
맞았습니다! 풀이
- subset 배열 저장하는 부분 수정
- $B = T - A$가 되는 경우 탐색할 때 Binary Search 사용
다음 두 가지를 반영해서 제출하니까 드디어 성공했다!
T = int(input())
n = int(input())
A = list(map(int, input().split()))
m = int(input())
B = list(map(int, input().split()))
subsetA, subsetB = [], [] # subset 합을 저장할 리스트
def binarySearch_lower(target, arr): # lower bound 인덱스 찾기
left = 0
right = len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
if mid == 0 or arr[mid - 1] != target:
return mid
else:
right = mid - 1
elif arr[mid] > target:
right = mid - 1
else:
left = mid + 1
return -1
def binarySearch_upper(target, arr): # upper bound 인덱스 찾기
left = 0
right = len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
if mid == len(arr)-1 or arr[mid + 1] != target:
return mid
else:
left = mid + 1
elif arr[mid] > target:
right = mid - 1
else:
left = mid + 1
return -1
for i in range(n): # A subset 저장
temp = 0
for j in range(i, n):
temp += A[j]
subsetA.append(temp)
for i in range(m): # B subset 저장
temp = 0
for j in range(i, m):
temp += B[j]
subsetB.append(temp)
res = 0
subsetB.sort()
for numA in subsetA: # Binary Search로 경우의 수 찾기
numB = T - numA
count = 0
if binarySearch_lower(numB, subsetB) != -1:
upper_bound = binarySearch_upper(numB, subsetB)
lower_bound = binarySearch_lower(numB, subsetB)
res += (upper_bound - lower_bound + 1)
print(res)
Binary Search로 특정 원소의 개수 구하는 방법
- $lower bound$ (원소가 등장하는 첫번째 인덱스)
- $upper bound$ (원소가 등장하는 마지막 인덱스)를 각각 찾고
- $(upper bound - lower bound) + 1$ = 원소의 갯수