본문 바로가기

BOJ/C++

[BOJ] 합이 0인 네 정수

문제

정수로 이루어진 크기가 같은 배열 A, B, C, D가 있다.

A[a], B[b], C[c], D[d]의 합이 0인 (a, b, c, d) 쌍의 개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 배열의 크기 n (1 ≤ n ≤ 4000)이 주어진다. 다음 n개 줄에는 A, B, C, D에 포함되는 정수가 공백으로 구분되어져서 주어진다. 배열에 들어있는 정수의 절댓값은 최대 228이다.

출력

합이 0이 되는 쌍의 개수를 출력한다.

 

7453 맞았습니다!! 165956 1292 C++14 / 수정 1049

 

1) 비슷한 유형의 문제 

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

 

2143번: 두 배열의 합

첫째 줄에 T(-1,000,000,000 ≤ T ≤ 1,000,000,000)가 주어진다. 다음 줄에는 n(1 ≤ n ≤ 1,000)이 주어지고, 그 다음 줄에 n개의 정수로 A[1], …, A[n]이 주어진다. 다음 줄에는 m(1≤m≤1,000)이 주어지고, 그 다음 줄에 m개의 정수로 B[1], …, B[m]이 주어진다. 각각의 배열 원소는 절댓값이 1,000,000을 넘지 않는 정수이다.

www.acmicpc.net

풀이

2020/02/10 - [BOJ/C++] - [BOJ] 두 배열의 합

 

[BOJ] 두 배열의 합

문제 한 배열 A[1], A[2], …, A[n]에 대해서, 부 배열은 A[i], A[i+1], …, A[j-1], A[j] (단, 1 ≤ i ≤ j ≤ n)을 말한다. 이러한 부 배열의 합은 A[i]+…+A[j]를 의미한다. 각 원소가..

jayrightthere.tistory.com

 

2) 완탐을 이용했다.

n의 크기가 4000인데 4000짜리 배열이 4개 있으므로 O(160000...)으로 네 배열을 한 번에 접근하려고 하면 안된다. 

그래서 A, B/  C, D 배열에서 나올 수 있는 모든 조합을 구한 후, T에서 뺀 값이 C, D 조합에 있는 구간을 구했다. 

 

3) 탐색 시간을 줄이기 위해 이분 탐색을 이용해서 

int target = T - (A, C 조합 중 한 값)

upper_bound(C,D의 조합에서 target보다 큰 값의 인덱스를 가져온다.)

lower_bound(C,D의 조합에서 target이상인 값의 인덱스를 가져온다.)

 

여기서 0이 되는 쌍의 개수는 upper - lower의 개수이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <vector>
#include <algorithm>
 
#define MAXX 4001
using namespace std;
 
typedef long long ll;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
 
    int n;
    cin >> n;
 
    int a[MAXX] = {0}, b[MAXX] = {0}, c[MAXX] = {0}, d[MAXX] = {0};
 
    vector<int> resL, resR;
 
    for (int i = 0; i < n; i++) {
        cin >>a[i] >> b[i] >> c[i] >> d[i];
    }
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++
        {
            resL.push_back(a[i] + b[j]);
        }
    }
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++
        {
            resR.push_back(c[i] + d[j]);
        }
    }
 
    sort(resR.begin(), resR.end());
 
    ll ans = 0;
    for (int i = 0; i < resL.size(); i++) {
        int diff = 0 - resL[i];
 
        vector<int> :: iterator up = upper_bound(resR.begin(), resR.end(), diff);
        vector<int> :: iterator lo = lower_bound(resR.begin(), resR.end(), diff);
        
        ans += up-lo;
    }
    cout << ans << '\n';
    return 0;
}
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

 

 

'BOJ > C++' 카테고리의 다른 글

도로 네트워크  (0) 2020.02.11
[BOJ] 두 배열의 합  (0) 2020.02.10
교수님은 기다리지 않는다  (0) 2020.02.10
lca2  (0) 2020.02.10
두 배열의 합  (0) 2020.02.09