본문 바로가기
알고리즘

백준 g4 2295 세 수의 합 c++

by kyj0032 2024. 2. 16.

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

 

2295번: 세 수의 합

우리가 x번째 수, y번째 수, z번째 수를 더해서 k번째 수를 만들었다라고 하자. 위의 예제에서 2+3+5=10의 경우는 x, y, z, k가 차례로 1, 2, 3, 4가 되며, 최적해의 경우는 2, 3, 4, 5가 된다. k번째 수가 최

www.acmicpc.net

 

문제

N개의 수로 이루어진 집합 U가 있을 때, 

각 원소 a, b, c, k를 골랐을 때 a + b + c = k 를 만족하는 최대 k 구하기

 

집합이므로 각 원소는 중복되지 않으나, a b c 는 서로 같아도 된다.

 

풀이

1. O(N^3*logN) 풀이

1) 세 원소를 고른다. 1000C3 -> N^3

2) 고른 세 원소의 합이 존재하는지 binary_search -> logN

 

그러나 N <= 10^3 으로 아마 시간초과가 뜰 듯 ... 

 

2. O(N^2l*logN) 풀이(https://blog.encrypted.gg/985)

1) 원본 배열에서 두 개의 합을 더해놓은 two 배열을 구함. -> N^2

2) two[i] + a[j] = a[k] ( == a[k] - a[j] = two[i])를 만족하는 a[k]를 구함.

    이때 for i, j 로 하면 시간복잡도가 N^3이 되어버리므로 for j, k로 해야 함.

 

수도 코드

//1. two 배열 구하기
for i, j: 0 ~ N
	two.push(a[i] + a[j])
   
 //2. two[i] + a[j] = a[k]를 만족하는 a[k] 구하기
 // == a[k] - a[j] = two[i]를 만족하는
 for j, k: 0 ~ N
 	if binary_search(a[k] - a[j], two[i])
    	ans = max(ans, a[k]

 

코드

/*boj g4 2295 세 수의 합*/
#include <algorithm>
#include <iostream>
#include <vector>
#define MAXN 1010
using namespace std;

int N;
vector<int> two;
int a[MAXN];
int ans = -99;
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> a[i];
    }

    // 1. two 배열 만들기
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            two.push_back(a[i] + a[j]);
        }
    }

    sort(two.begin(), two.end());

    // 2. two[i] + a[j] = a[k] 일 때, two[i]가 존재하는 지 확인
    for (int k = 0; k < N; k++) {
        for (int j = 0; j < N; j++) {
            if (binary_search(two.begin(), two.end(), a[k] - a[j])) {
                ans = max(ans, a[k]);
            }
        }
    }

    cout << ans << "\n";
}

'알고리즘' 카테고리의 다른 글

백준 s5 10815 숫자 카드 c++  (0) 2024.02.17
백준 s2 1654 랜선 자르기 c++  (0) 2024.02.16
백준 s2 18870 좌표 압축 c++  (0) 2024.02.15
백준 s2 11501 주식 c++  (0) 2024.01.26
백준 g5 2170 선 긋기 c++  (0) 2024.01.26