Problem C 풀이 (C++)
문제 링크 : https://codeforces.com/contest/1538/problem/C
모든 경우를 확인하는 경우는 시간 초과가 된다.
i,j 쌍을 찾는 조건을 보면 간단히 말해서 l <= ai + aj <= r 조건이 맞는 서로 다른 index 쌍의 개수를 찾는 것이다.
배열을 오름차순으로 정렬하고 차례대로 순회하며
각 index를 기준으로 잡고 index보다 큰 범위를 이분 탐색을 통해 조건의 범위를 찾는다.
i < j 이기 때문에 기준으로 잡은 index는 i가 되고 조건에 맞는 j의 개수를 구한다.
l <= ai + aj <= r 조건은 l - ai <= aj <= r - ai 로 볼 수 있다.
조건에 맞는 j의 개수는 l - ai와 r - ai를 구하면 범위를 구하여 개수를 찾을 수 있기 때문에
각 index마다 이분 탐색을 2번을 수행하게 된다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int t; cin >> t; while (t--) { int n, l, r; cin >> n >> l >> r; long long answer = 0; vector<int> arr(n, 0); for (int i = 0; i < n; i++) cin >> arr[i]; sort(arr.begin(), arr.end()); for (int i = 0; i < n; i++) { int ai = arr[i]; int l_ai_idx = n; int r_ai_idx = -1; int s = i + 1, e = n - 1, m; while (s <= e) { m = (s + e) / 2; if (arr[m] >= l - ai) { if (l_ai_idx > m) l_ai_idx = m; e = m - 1; } else s = m + 1; } s = i + 1, e = n - 1; while (s <= e) { m = (s + e) / 2; if (arr[m] <= r - ai) { if (r_ai_idx < m) r_ai_idx = m; s = m + 1; } else e = m - 1; } if (l_ai_idx != -1 && r_ai_idx != n && r_ai_idx - l_ai_idx >= 0) answer += r_ai_idx - l_ai_idx + 1; } cout << answer << endl; } return 0; } | cs |
댓글
댓글 쓰기