티스토리 뷰

728x90

문제 링크

www.acmicpc.net/problem/7453

 

7453번: 합이 0인 네 정수

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

www.acmicpc.net

 

풀이

$a+b+c+d = 0$인 조합의 개수를 찾아야합니다. 나이브하게 풀면 $O(N^4)$의 복잡도로 통과하지 못합니다.

 

1) 이를 $a+b = -(c+d)$로 생각하여 양 변을 따로 봅시다.

각각 $(a+b)$, $(c+d)$의 모든 조합을 구하는데 $O(N^2)$의 복잡도가 듭니다.

 

2) $a+b$ 배열의 각 원소마다, $c+d = -(a+b)$를 만족하는 $c+d$ 조합의 수를 찾아줍시다.

upper bound와 lower bound를 이용하면 원하는 구간의 길이를 $O(logN)$에 구할 수 있습니다. 

 

총 시간복잡도 $O(N^2\cdot logN)$으로 충분히 통과가 가능합니다.

 

 

정답 코드

#include <bits/stdc++.h>

#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
using vi = vector<int>;

vi x, y;
int n, a[4444], b[4444], c[4444], d[4444];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    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++) {
            x.push_back(a[i] + b[j]);
            y.push_back(c[i] + d[j]);
        }
    }
    sort(all(x));
    sort(all(y));
    ll ans = 0;
    for (int i = 0; i < n * n; i++) {
        ans += upper_bound(all(y), -x[i]) - lower_bound(all(y), -x[i]);
    }
    cout << ans;
}
728x90

'알고리즘 > 문제 풀이' 카테고리의 다른 글

[BOJ] 백준 9328 열쇠  (0) 2021.03.08
[BOJ] 백준 7579 앱  (1) 2021.03.08
[BOJ] 백준 2887 행성 터널  (0) 2021.03.08
[BOJ] 백준 2623 음악프로그램  (0) 2021.03.08
[BOJ] 백준 2098 외판원 순회  (0) 2021.03.08
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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
글 보관함