-
백준 2473번 : 세 용액 (C++)알고리즘/BOJ 2021. 7. 13. 21:42
문제 : https://www.acmicpc.net/problem/2473
2473번: 세 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 3 이상 5,000 이하의 정수이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상
www.acmicpc.net
정수 배열에서 3개의 수를 골라 그 3개의 합이 최대한 0에 가까운 조합을 찾는문제이다. 먼저 N의 범위를 보자. N의 범위는 5000이하인 수로 O(N^2) 방법으로 시간내 풀 수 있음을 추측가능하다.
만약 골라야 하는 수가 3개가 아니고 2개라면 투 포인터나 해쉬맵으로 쉽게 해결할 수 있을 것이다. 그런 경우에는 배열의 사전에 정렬해줘야하므로 O(NlogN + N)의 복잡도를 가진다. 그럼 만약 골라야하는 수 1개는 고정시켜두고 나머지에 대해서만 투 투인터 방법을 사용하는것은 어떨까? 즉 3번째 수를 일단 골랐다고 하면 4번째수 ~ N번째 수에 대해서만 투 포인터로 타겟들을 찾는것이다. 그럼 시간복잡도가 O(NlogN + N^2) = O(N^2)으로 시간내에 충분히 풀 수 있다.
#include <iostream> #include <vector> #include <algorithm> #include <cmath> #include <set> #include<map> #include <queue> typedef long long ll; using namespace std; int n; ll p[100002]; int main() { cin.tie(NULL); ios::sync_with_stdio(false); cin >> n; for(int i=1; i<=n; i++){ cin >> p[i]; } sort(&p[1], &p[n+1]); ll sum = INT64_MAX; ll a1, a2, a3; for(int i=1; i<=n; i++){ int j = i+1; int k = n; while(j < k){ if(sum > abs(p[i] + p[j] + p[k])){ sum = abs(p[i] + p[j] + p[k]); a1 = p[i]; a2 = p[j]; a3 = p[k]; } if(p[i] + p[j] + p[k] < 0){ j++; } else{ k--; } } } cout << a1 << ' ' << a2 << ' ' << a3; }
'알고리즘 > BOJ' 카테고리의 다른 글
백준 2513번 : 통학버스 (C++) (0) 2021.12.06 백준 1744번 : 수 묶기 (C++) (0) 2021.07.07 백준 2568번 : 전깃줄-2 (C++) (3) 2021.07.02 백준 1799번 : 비숍 (C++) (0) 2021.07.02 백준 11505번 : 구간 곱 구하기 (C++) (0) 2021.07.01