카테고리 없음

2024 - 01- 20 C++ 코딩테스트 10주완성 D+68

Jang_^ 2025. 1. 20. 18:07
백준 3273 문제 - 두 수의 합

 

n개의 서로 다른 양의 정수 a1, a2, ..., an으로 이루어진 수열이 있다.

 

ai의 값은 1보다 크거나 같고, 1000000보다 작거나 같은 자연수이다.

 

자연수 x가 주어졌을 때, ai + aj = x (1 ≤ i < j ≤ n)을 만족하는 (ai, aj)쌍의 수를 구하는 프로그램을 작성하시오.

 

입력

 

첫째 줄에 수열의 크기 n이 주어진다.
다음 줄에는 수열에 포함되는 수가 주어진다.
셋째 줄에는 x가 주어진다. (1 ≤ n ≤ 100000, 1 ≤ x ≤ 2000000)

 

출력

 

문제의 조건을 만족하는 쌍의 개수를 출력한다.

 

 

#include<bits/stdc++.h>

using namespace std;

int l,r,n,x,ret;

int main()
{
    cin >> n;
    vector<int> a(n);

    for(int i =0; i < n; i++) cin >> a[i];

    cin >> x;
    sort(a.begin(),a.end());
    l = 0, r = n - 1;
    while(l < r)
    {
        if(a[l] + a[r] == x) r--,ret++;
        else if(a[l] + a[r] > x) r--;
        else if(a[l] + a[r] < x) l++;
    }

    cout << ret;
}

 

더해서 X가 나오는 쌍을 주어진 집합 전부 이중반복문을 돌려 계산하면

 

1 ≤ n ≤ 100000 범위이므로 1,000,000 X 1,000,000 은 1억을 가뿐히 넘으므로 시간초과가 난다!

 

그래서 이용하는 것이 투포인터이다.

 

왼쪽부터 탐색하는 포인터와 오른쪽부터 탐색하는 포인터 두개를 이용하는 것이다.

 

입력받은 집합을 오름차순으로 정렬시켜준뒤,

 

투 포인터가 가르치는 원소의 합이 x보다 클 시, 오른쪽 포인터를 이동시켜 좀더 작은 수로 이동시켜주고

 

x보다 작을 시, 왼쪽 포인터를 이동시켜 좀더 큰 수로 이동시켜준다.

 

그리고 x가 나올시, 쌍의 개수를 저장하는 ret++를 시켜주고 오른쪽 포인터를 감소시켜준다.