알고리즘/투 포인터

[백준] 1253 - 좋다 Python

기억은 RAM, 기록은 HDD 2022. 8. 13. 14:51

https://www.acmicpc.net/problem/1253

 

1253번: 좋다

첫째 줄에는 수의 개수 N(1 ≤ N ≤ 2,000), 두 번째 줄에는 i번째 수를 나타내는 Ai가 N개 주어진다. (|Ai| ≤ 1,000,000,000, Ai는 정수)

www.acmicpc.net

N 개의 수 중 자기 자신이 아닌 다른 두 수의 합으로 나타낼 수 있는 수를 구하는 문제다.

- 입력을 받은 N 개의 수를 정렬한다. (nlogn)

- 투 포인터 알고리즘을 이용해 0 번째 인덱스부터 N-1 번째 인덱스까지 두 수를 조합해 현재 수를 만들 수 있는 경우를 완전탐색한다.

- 한번 탐색한 숫자에 대해 다시 불필요한 탐색을 하지 않도록 각 숫자별로 해시테이블에 다른 두 수의 합으로 만들 수 있는지 1, -1 로 저장한다.

 

자기 자신이 아닌 두 수의 합으로 나타낼 수 있어야 하기 때문에 start 또는 end 가 자기 자신일 경우 continue 로 넘어갈 수 있도록 한다.

from sys import stdin
from collections import defaultdict

def find(x):
    global i
    start = 0
    end = N-1
    while start < end:
        if start == i:
            start = i+1
            continue
        if end == i:
            end = i -1
            continue
        s = arr[start] + arr[end] 
        if s == x:
            return True
        elif s > x:
            end -= 1
        else:
            start += 1
    return False

hash_table = defaultdict(int)

N = int(stdin.readline())
arr = list(map(int,stdin.readline().split()))
arr.sort()

cnt = 0
for i in range(N):
    is_exist = hash_table[arr[i]]
    if is_exist == 1:
        cnt += 1
    elif is_exist == -1:
        continue
    else:
        if find(arr[i]):
            hash_table[arr[i]] = 1
            cnt += 1
        else:
            hash_table[arr[i]] = -1

print(cnt)