https://www.acmicpc.net/problem/7453
이 문제의 경우 처음에 투포인터로 분류가 되어있어 풀려고 했는데 투포인터가 불가능 하게 리스트가 4개 있어서 안될거 같다는 생각을 했다 그래서 투포인터를 사용하기 위해서는 어떻게 해야할까라고 생각해봤을 때 a와 b의 합을 c와 d의 합의 모든 경우의 수로 리스트를 만들려고 하였다
즉 c와 d의 합을
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cmp.push_back(v[2][i] + v[3][j]);
}
}
이런 식으로 만들어 주고
a와 b의 합의 - 를 붙인거가 c와 d를 합친 cmp에 있는 갯수를 더해서 경우의 수를 구하면 된다 근데 갯수를 어떻게 구할지를 생각해보면 -(a+b) 에 대한 거를 algorithm 헤더에 있는 lower_bound와 upper_bound를 이분 탐색으로 해당 수를 찾아 낮은 인덱스 와 높은 인덱스를 찾아 차이가 해당 수의 갯수이니 이를 더해주면 된다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> v[4];
vector<int> cmp;
long long ans = 0;
int n;
int main() {
cin >> n;
for (int i = 0; i < 4; i++) {
v[i].resize(n + 1);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < 4; j++) {
cin >> v[j][i];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cmp.push_back(v[2][i] + v[3][j]);
}
}
sort(cmp.begin(), cmp.end());
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int tmp = v[0][i] + v[1][j];
int lowIdx = lower_bound(cmp.begin(), cmp.end(), -tmp)- cmp.begin();
int upIdx = upper_bound(cmp.begin(), cmp.end(), -tmp) - cmp.begin();
ans += (upIdx - lowIdx);
}
}
cout << ans;
}
'백준(코테준비) > 이분탐색' 카테고리의 다른 글
백준 2143 / CPP / 이분탐색 / 누적합 (0) | 2025.01.27 |
---|---|
백준 1253 / CPP / 이분탐 (0) | 2025.01.13 |
백준 12738 (1) | 2024.12.02 |
백준 3079/ c++ (0) | 2024.10.21 |