문제
https://www.acmicpc.net/problem/7453
7453번: 합이 0인 네 정수
첫째 줄에 배열의 크기 n (1 ≤ n ≤ 4000)이 주어진다. 다음 n개 줄에는 A, B, C, D에 포함되는 정수가 공백으로 구분되어져서 주어진다. 배열에 들어있는 정수의 절댓값은 최대 228이다.
www.acmicpc.net
문제 요약
정수로 이루어진 크기가 같은 배열 A, B, C, D가 있을 때,
A[a], B[b], C[c], D[d]의 합이 0이 되는 쌍의 개수를 출력한다.
+ 각 배열의 크기 n은 1이상 4000이하이다.
코드
#include <iostream>
#include <algorithm>
#include <vector>
#define MAX_N 4000
using namespace std;
int n;
int arr[4][MAX_N + 1];
vector<int> sum_ab, sum_cd;
void input() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 0; i < n; i++) {
int a, b, c, d;
cin >> a >> b >> c >> d;
arr[0][i] = a;
arr[1][i] = b;
arr[2][i] = c;
arr[3][i] = d;
}
}
void solve() {
// 배열 A와 B, C와 D를 통해 나올 수 있는 모든 합들을 저장
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sum_ab.push_back(arr[0][i] + arr[1][j]);
sum_cd.push_back(arr[2][i] + arr[3][j]);
}
}
// 오름차순 정렬
sort(sum_ab.begin(), sum_ab.end());
sort(sum_cd.begin(), sum_cd.end());
// sum_ab와 sum_cd의 길이가 최대 16,000,000이므로 cnt는 최대 16,000,000 * 16,000,000이 가능
long long cnt = 0;
// -sum_ab[i]와 같은 값이 sum_cd에 몇 개 있는지 모두 체크 (합이 0이어야 하므로)
for (int i = 0; i < sum_ab.size(); i++) {
// -sum_ab[i]가 sum_cd에 처음 등장하는 인덱스 탐색
int cd_pre = lower_bound(sum_cd.begin(), sum_cd.end(), -sum_ab[i]) - sum_cd.begin();
// -sum_ab[i]가 sum_cd에 마지막에 등장하는 인덱스 탐색
int cd_end = upper_bound(sum_cd.begin(), sum_cd.end(), -sum_ab[i]) - sum_cd.begin();
cnt += (cd_end - cd_pre);
}
cout << cnt;
}
int main() {
input();
solve();
}
코드 설명
1. 배열 A, B, C, D를 입력 받는다.
2. 배열 A와 B, 배열 C와 D를 통해 나올 수 있는 모든 합들을 저장하는 배열 sum_ab, sum_cd를 생성한다.
3. lower_bound, upper_bound를 사용하기 위해 두 배열을 오름차순 정렬한다.
4. -sum_ab[i]가 sum_cd에 존재하는 개수를 모두 센다.
+ 개수가 최대 4000 × 4000 × 4000 × 4000 이므로 long long형을 사용한다.
'Algorithm Problems > 투 포인터' 카테고리의 다른 글
[백준/C++] 2018번: 수들의 합 5 (1) | 2024.03.27 |
---|---|
[백준/C++] 15565번: 귀여운 라이언 (0) | 2024.03.26 |
[백준/Python] 2470번: 두 용액 (1) | 2023.11.08 |
[백준/Python] 1644번: 소수의 연속합 (2) | 2023.11.07 |
[백준/Python] 26091번: 현대모비스 소프트웨어 아카데미 (1) | 2023.09.24 |