[Python] 백준/BOJ 17124번: 두 개의 배열 (Silver 3)

2025. 10. 3. 02:45·Algorithm/백준 (BOJ)
반응형

💻 Problem

문제 보러 가기

 

정수 배열 A와 B가 있다. A는 총 n개의 서로 다른 양의 정수를 포함하고 B는 총 m개의 서로 다른 양의 정수를 포함한다.

A, B를 이용해서 길이가 n인 새로운 배열 C를 만들어보자.

C[i] 는 배열 B에 있는 값 중 A[i] 에 가장 가까운 값 (절댓값 차이가 가장 작은 값)으로 정의된다. 
만약 이 조건을 만족하는 값들이 여럿 있는 경우, 그 중 가장 크기가 작은 값으로 정의된다.
예를 들어 A = [20, 5, 14, 9] 그리고 B = [16, 8, 12] 라고 해보자.

C[1] = 16 이다 - 왜냐하면 B[1] = 16이 A[1] = 20에 가장 가깝기 때문이다.
C[2] = 8 이다 - 왜냐하면 B[2] = 8이 A[2] = 5에 가장 가깝기 때문이다.
C[3] = 12 이다 - 왜냐하면 B[1] = 16 와 B[3] = 12 모두 A[3] = 14에 가장 가깝지만, B[3]의 값이 더 작기 때문이다.
C[4] = 8이다.
이 예제의 경우 C = [16, 8, 12, 8]으로 정의된다.

두 배열 A와 B가 주어졌을 때, 새로운 배열 C를 계산하여 배열 C에 포함된 값들의 합을 구하는 프로그램을 작성하시오.

 

💡 Approach

A의 원소를 하나씩 살펴보며 B 배열에서 자신과 가장 가까운 값(절댓값 차이가 가장 작은 값)을 찾는다.

A[i]는 target이고 target과 가장 가까운 값을 B 배열에서 찾아야 한다.

A 배열과 B 배열의 최대 길이가 각각 10^6이므로 브루트포스로 풀면 시간 초과가 뜨게 된다.

이분탐색으로 구현해 보자.

 

A의 원소 하나하나씩 이분탐색으로 B에서 자신과 가장 가까운 값을 찾는다.

closest_idx, closest_val을 둬서 target과 가장 가까운 값의 인덱스와 값을 기록했다.

 

반복문을 활용해서 이분탐색을 구현했다.

이전보다 절댓값 차이가 더 작다면 closest_val 갱신하고, 만약 같다면 인덱스가 더 작을 때만 갱신한다.

타겟이 B[mid]보다 작으면 왼쪽을, 더 크면 오른쪽을 탐색한다.

기록해 둔 closest_idx가 이분탐색을 통해 찾은 인덱스이다.

B[closest_idx]를 리턴하면 된다.

 

✏️ Solution

import sys
input = sys.stdin.readline

def binary_search(target):
    start, end = 0, m - 1
    closest_idx, closest_val = m - 1, 10 ** 9 - 1
    
    while start <= end:
        mid = (start + end) // 2

        # 이전보다 절대값 차이가 더 작다면 closest_val 갱신
        # 같다면 더 작은 인덱스를 우선
        compare_val = abs(target - B[mid])
        if (closest_val > compare_val) or (closest_val == compare_val and closest_idx > mid):
            closest_val = compare_val
            closest_idx = mid

        # 타겟이 더 작으면 왼쪽 탐색
        if target < B[mid]:
            end = mid - 1

        # 타겟이 더 크면 오른쪽 탐색
        else:
            start = mid + 1
            
    return B[closest_idx]

T = int(input())
for _ in range(T):
    n, m = map(int, input().split())
    A = list(map(int, input().split()))
    B = sorted(map(int, input().split()))
    res = 0

    for a in A:
        res += binary_search(a)
    
    print(res)

⏱️ 시간복잡도

A 배열의 원소 개수: n (최대 10^6)

B 배열의 원소 개수: m (최대 10^6)

 

이분 탐색의 시간복잡도는 log N 이므로 이 코드의 시간복잡도는 n * log m이 된다.

10^6을 2의 제곱으로 치환하면 2^20이다.

대입하면 10^6 * 20 = 2 * 10^7이 된다.

반응형
'Algorithm/백준 (BOJ)' 카테고리의 다른 글
  • [Python] 백준/BOJ 20207번: 달력 (Gold 5)
  • [Python] 백준/BOJ 5376번: 소수를 분수로 (Silver 1)
  • [Python] 백준/BOJ 18234번: 당근 훔쳐 먹기 (Gold 3)
  • [Python] 백준/BOJ 2597번: 줄자접기 (Silver 3)
올콩
올콩
콩 심은 데 콩 난다
  • 올콩
    콩스토리
    올콩
  • 전체
    오늘
    어제
    • 분류 전체보기 (206)
      • SSAFY (10)
      • Algorithm (120)
        • 이론 (6)
        • 백준 (BOJ) (112)
        • 프로그래머스 (1)
        • 코드트리 (1)
      • Trouble Shooting (10)
      • Frontend (7)
      • React (17)
      • Next.js (5)
      • Vue (4)
      • Node.js (2)
      • HTML (9)
      • DevOps (4)
        • Git (4)
      • Language (9)
        • JavaScript (0)
        • Java (9)
      • Embedded (1)
      • CS (5)
        • Network (1)
        • Blockchain (4)
      • 자격증 (2)
      • 기타 (1)
        • Tistory (1)
  • 블로그 메뉴

    • GitHub
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    React
    순열
    알고리즘
    구현
    재귀
    SSAFYcial
    Error
    SSAFY
    bfs
    블록체인
    브루트포스
    그리디
    티스토리챌린지
    힙
    파이썬
    우선순위큐
    Heap
    백트래킹
    Next.js
    강의
    오블완
    dfs
    수학
    Java
    Algorithm
    중복순열
    html5
    싸피
    DP
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
올콩
[Python] 백준/BOJ 17124번: 두 개의 배열 (Silver 3)
상단으로

티스토리툴바