====== 두 용액 ====== ===== 풀이 ===== * [[ps:problems:boj:3273]] 처럼 두 수의 합이 X가 되는 쌍을 찾는 문제를 풀기 위해서는 소팅과 [[ps:투 포인터]]를 안쓰고도 그냥 해싱을 통해서 푸는 것이 더 빨랐다. 그러나 이 문제처럼 두 수의 합이 X에 가장 가까운 쌍을 찾는 문제라면, 소팅 후에 [[ps:투 포인터]]나 [[ps:이진 검색]]을 써야 한다. * 투 포인터 방법은 소팅 후에 양 끝에서 출발하는 포인터 2개를 갱신해 나가는 것. 합이 X보다 작으면 왼쪽 포인터를 증가시키고, 합이 X보다 크면 오른쪽 포인터를 감소시킨다. 이 방식으로는 소팅에 O(nlogn), 탐색에 O(n), 총 O(nlogn)에 풀수 있다. * 이진 검색은, 정렬 후에 각 숫자 X에 대해서 -X에 가장 가까운 값을 이분탐색으로 찾는 것을 반복하면 된다. 정렬에도 O(nlogn) 탐색에 O(nlogn)이 걸려서 총 시간 복잡도는 똑같이 O(nlogn)이지만, 좀더 느리다. * 그리고, 역시 시간 복잡도는 같지만 좀더 간단하게 구현 가능한 방법이 있다. 합이 0에 가장 가까운 두 수는 절대값을 기준으로 소팅했을때 인접한 위치에 존재한다. 따라서, 그냥 절대값을 기준으로 소팅하고 인접한 두 수들만 비교해주면 된다. 시간 복잡도는 역시 소팅에 O(nlogn), 탐색에 O(n), 총 O(nlogn). * 이 문제에서는 마지막 방식으로만 구현했다. 투포인터 방식으로 구현한 코드는 [[ps:problems:boj:2467]]을 참고. [[ps:problems:boj:2467]]은 이 문제와 동일한데 데이터가 소팅이 된 채로 들어오는 것만 다르다. ===== 코드 ===== """Solution code for "BOJ 2470. 두 용액". - Problem link: https://www.acmicpc.net/problem/2470 - Solution link: http://www.teferi.net/ps/problems/boj/2470 Tags: [Sort] """ def main(): N = int(input()) nums = [int(x) for x in input().split()] nums.sort(key=abs) _, pair = min((abs(sum(pair)), pair) for pair in zip(nums, nums[1:])) print(*sorted(pair)) if __name__ == '__main__': main() {{tag>BOJ ps:problems:boj:골드_5}}