-
[BOJ] 2143 두 배열의 합PS/BOJ 2020. 7. 20. 00:06
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)이 주어지고, 그 다
www.acmicpc.net
알고리즘: 투포인터
시간복잡도: O(N2logN2)
접근:
1. 부 배열은 연속적이다.
2. A 부 배열의 합 + B 부 배열의 합 = T를 만족하는 가짓수 구하기
(합 + 합 = T 가짓수 구하기)
->
2번 조건을 보면 이 문제는 투포인터 문제라는 것을 알 수 있다.
다만 기본적인 투포인터 문제에서 1번 조건의 부 배열이라는 요소만 추가되었는데,
여기서 부 배열이 연속적이라는 것만 캐치해내면 된다.
부 배열이 연속적이기 때문에 연속합을 구하는 DP 문제처럼
i~j 까지의 구간합을 다 구해서 새로운 배열에 넣어주면 된다.
여기서 O(N2)의 시간복잡도가 걸리고,
투포인터를 사용하기 위해 정렬을 하기 때문에 최종 시간복잡도는, O(N2logN2)
code// 2143: 두 배열의 합 #include<iostream> #include<algorithm> using namespace std; int T, n, m, la, lb, st, en; int in[1001], a[1001*1001], b[1001*1001]; long long int ans, na, nb; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> T >> n; for (int i = 1; i <= n; ++i) { cin >> in[i]; in[i] += in[i-1]; } for (int i = 1; i <= n; ++i) for (int j = i; j <= n; ++j) a[la++] = in[j] - in[i-1]; cin >> m; for (int i = 1; i <= m; ++i) { cin >> in[i]; in[i] += in[i-1]; } for (int i = 1; i <= m; ++i) for (int j = i; j <= m; ++j) b[lb++] = in[j] - in[i-1]; sort(a, a+la); sort(b, b+lb); en = lb-1; while (st < la && en >= 0) { int sum = a[st] + b[en]; if (sum == T) { na = 1, nb = 1; st++, en--; while (a[st-1] == a[st] && st < la){ st++, na++; } while (b[en+1] == b[en] && en >= 0){ en--, nb++; } ans += na * nb; } else if (sum < T) st++; else en--; } cout << ans; return 0; }
'PS > BOJ' 카테고리의 다른 글
[BOJ] 14427 수열과 쿼리 15 (0) 2020.08.23 [BOJ] 2342 Dance Dance Revolution (0) 2020.07.20 [BOJ] 2038 골롱 수열 (0) 2020.07.17 [BOJ] 1987 알파벳 (0) 2020.07.17 [BOJ] 1932 정수 삼각형 (0) 2020.07.16