- 문제 링크 : boj.kr/2143
- 난이도 : G3
- 태그 : 누적합, 이분탐색
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)이 주어지고, 그
www.acmicpc.net
코드
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define INF 0x7FFFFFFF
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll, ll>;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll T;
cin >> T;
int n;
cin >> n;
vector<ll> A(n+1);
for(int i = 1; i <= n; i++) {
cin >> A[i];
A[i] += A[i-1];
}
int m;
cin >> m;
vector<ll> B(m+1);
for(int i = 1; i <= m; i++) {
cin >> B[i];
B[i] += B[i-1];
}
vector<ll> arr1, arr2;
for(int i = 0; i <= n; i++) {
for(int j = i + 1; j <= n; j++) {
arr1.emplace_back(A[j]-A[i]);
}
}
for(int i = 0; i <= m; i++) {
for(int j = i + 1; j <= m; j++) {
arr2.emplace_back(B[j]-B[i]);
}
}
sort(all(arr2));
ll ans = 0;
for(int i = 0; i < arr1.size(); i++) {
ll target = T - arr1[i];
ans += upper_bound(all(arr2), target) - lower_bound(all(arr2), target);
}
cout << ans;
return 0;
}
풀이
누적합을 이용해 각각 O(N^2), O(M^2)으로 모든 부분배열의 합을 구해둔다.
A의 부분배열의 합을 순회하며 그 값에 해당하는 B의 부분배열의 합의 개수를 구한다.
이떄 N^2 * M^2으로 모든 경우를 확인하면 시간 초과가 나므로 B의 부분배열의 합의 개수를 이분탐색으로 구해준다.
이분탐색을 사용하므로 정렬해야 함에 유의해야 한다.
728x90
'PS' 카테고리의 다른 글
BOJ 1286 : 부분 직사각형 (1) | 2024.03.05 |
---|---|
BOJ 2036 : 수열의 점수 (0) | 2024.03.04 |
BOJ 1253 : 좋다 (0) | 2024.03.02 |
BOJ 16566 : 카드 게임 (0) | 2024.03.01 |
BOJ 15900 : 나무 탈출 (1) | 2024.02.29 |