본문 바로가기
PS 문제 풀이/Baekjoon

[BOJ] 백준 2470 두 용액

by 까망 하르방 2021. 2. 28.
반응형

출처: https://www.acmicpc.net/problem/2470

 Input 

5

-2 4 -99 -1 98

 

 Output 

-99 98

※ 같은 문제 다른 풀이: [Jungol] 2306 두 용액 

 

[Jungol] 정올 2306 두 용액

출처: [Jungol] 2306 두 용액  Input 5 -2 4 -99 -1 98  Output -99 98 같은 문제 다른 풀이: [BOJ] 2470 두 용액 ① 실제로 채점되는 Input Data는 정렬되어 있지 않기 때문에 주어진 숫자 정렬 ex) {-2 4 -99..

zoosso.tistory.com

 

가장 가까운 두 수의 합이 0에 가장 가까운 두 수를 구하는 것입니다.

* 양수만 주어지거나 음수만 주어질 수도 있다

 

부호를 고려하지 않기 위해 절대값 기준으로 숫자들을 저장

(부호는 pair를 이용해서 같이 저장)

arr = { -99, -4, 1, -2, 98 }

vector = {(1, 1), (2, -1), (4, -1), (98, 1), (99, -1)}

              → {1, -2, -4, 98, 99} 

그 후 인접한 두 수 합을 구한 해서 0에 가장 가까운 두 수를 찾습니다.(갱신)

ex) 1 - 2 / -2 - 4 / -4 + 98 / 98 + 99

 

Q. 절대값 기준으로 정렬한 후, 왜 인접한 두 숫자만 비교하면 될까?

정렬된 세 개의 숫자가 존재한다고 A, B, C 했을 때,

인접하지 않은 두 수의 합 A + C 와 인접한 두 수의 합 A + B or B + C 

① 부호가 모든 같은 경우: [- - -], [+ + +]

    → 어떤 숫자이든 |A + C| > |A + B| 로 A+C가 0과 더 멀리 떨어져 있는것을 확인

 A와 C가 같은 부호이면서 B만 다른 부호 [+ - +], [- + -]

    → |A + C| 보다 |A + B| or |B + C|가 0하고 가깝습니다.

③ A와 C의 부호가 다른 경우 [- + +], [- - +], [+ + -], [+ - -]

    → [- + +]: |A + B| < |A + C|

    → [- - +]: |B + C| < |A + C|

    → [+ + -]: |B + C| < |A + C|

    → [+ - -]: |A + B| < |A + C|

▶ |A + C| > |A + B| or |B + C| 로서, 절대값 기준으로 정렬한 후 인접한 두 수만 비교하면 됩니다.


* 최대 10억의 수를 표현하기 위해 long long 사용

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 2000000001
typedef long long ll;
vector<pair<ll, int> > vec;
 
int main() {
    int N;
    ll firstAns, secondAns, num, sum = MAX;
 
    scanf("%d", &N);
    while (N--) {
        scanf("%lld", &num);
        if (num > 0)
            // 양수
            vec.push_back({num, 1}); 
        else
            // 음수
            vec.push_back({num * -1, -1}); 
    }
 
    sort(vec.begin(), vec.end());
       // arr = {-99 -2 4 -1 98}
    
    // [절대값]: 1  2  4 98 99
    // [부호]:   -  -  +  +  -
    ll temp;
    for (int i = 1; i < vec.size(); i++) {
        temp = vec[i].first * vec[i].second 
            + vec[i - 1].first * vec[i - 1].second;
 
        if (temp < 0)
            temp *= -1;
        if (sum < 0)
            sum *= -1;
 
        if (temp < sum) {
            firstAns = vec[i].first * vec[i].second;
            secondAns = vec[i - 1].first * vec[i - 1].second;
            sum = temp;
        }
    }
 
    if (firstAns <= secondAns) printf("%lld %lld", firstAns, secondAns);
    else printf("%lld %lld", secondAns, firstAns);
}

 

반응형

'PS 문제 풀이 > Baekjoon' 카테고리의 다른 글

[BOJ] 백준 2110 공유기 설치  (0) 2021.02.28
[BOJ] 백준 2670 연속부분최대곱  (0) 2021.02.28
[BOJ] 백준 10986 나머지 합  (0) 2021.02.28
[BOJ] 백준 5397 키로거  (0) 2021.02.28
[BOJ] 백준 2161 카드 1  (0) 2021.02.28

댓글