Problem Analysis:
for any triangle with edges a, b, c we know that
(1) a + b > c
(2) b + c > a
(3) c + a > c
for being a valid triangle it must follow all these . we can use a brute force algorithm O(n^3) with 3 nested loops and checking the validity of those selected edges of those but it's too big so we will try to make this better. So first we sort the array of lengths for simplicity.
Than for each 'e1' we select another edge after that and thats 'e2' and we know we sorted the aray so e1<=e2. After that we search the maximum element 'e3' that follows all three of those triangle validity formula we wrote above.
we already know that e1+e3 > e2 and e2 + e3 > e1 as they are sorted and e1<= e2 < e3 so we just need to find the maximum edge length for which e1+e2>e3. and than we also know that all the edges between e2 and e3 also makes valid triangles. because they also follow all the three rules.
So we just search index of (e1+e2-1) using binary search.
here we searched for (e1+e2-1) we used -1 because e1+e2 , e1, e2 these three can not actually make a valid triangle. After finding the upper bound of e3 (e1+e2-1) we just add the difference of the index of e2 and e3 and repeat it for the next e1, e2' . so our algorithm now becomes
O(N^2 + Nlog(N)) = O(N^2) that easily passes.
O(N^2 + Nlog(N)) = O(N^2) that easily passes.
for better visualization go here
Here goes the code:
- #include <bits/stdc++.h>
- using namespace std;
- int main(){
- int ts;
- scanf("%d", &ts);
- for(int p = 1; p <= ts; p++){
- int n;
- scanf("%d", &n);
- vector<int>v;
- for(int i = 0; i <n; i++){
- int a;
- scanf("%d", &a);
- v.push_back(a);
- }
- sort(v.begin(), v.end());
- long long unsigned sum = 0;
- for(int i = 0; i <n-2; i++){
- for(int j = i+1; j<n-1; j++){
- sum+= upper_bound(v.begin(), v.end(),v[i]+v[j]-1)-v.begin()-j-1;
- }
- }
- printf("Case %d: %llu\n",p, sum);
- }
- return 0;
- }
No comments:
Post a Comment