Pagini recente » Cod sursa (job #2141240) | Cod sursa (job #2375363) | Monitorul de evaluare | Cod sursa (job #2029799) | Cod sursa (job #3324479)
/*
ai N betisoare, fiecare cu o lungime
vrei sa aflii in cate moduri poti alege 3 betisoare astefl incat ele sa poata forma un triunghi
regula triunghiului:
pentru orice 3 laturi: a + b >= c, unde c este cea mai mare
Obs: pentru problema asta, este permisa chiar si egalitatea, pentru ca sunt valide si cazurile
degenerate unde triunghiul are un unghi de 180
de ce este nevoie sa sortam?
daca pastram betisoarele in ordine crescatoare:
v[i] <= v[j] <= v[k]
atunci singura conditie de verificat este
v[i] + v[j] >= v[k]
celelalte doua inegalitati sunt automat adevarate pentru ca v[k] este cel mai mare
idee:
pentru fiecare pereche de betisoare (i, j) cautam cate betisoare k > j satisfac:
v[i] + v[j] >= v[k]
asta este exact o cautare binara pe intervalul [j+1...n-1]
rezultatul:
daca cel mai mare k valid este r, atunci avem:
r - j betisoare valide
si le adaugam la rezultat
de ce este corect bs?
v este sortat
conditia v[k] <= suma este un predicat monotomic
complexitate temporala:
sortare: O(nlogn)
bucla: O(n^2)
bs: O(longn)
total: O(n^2logn)
*/
#include <bits/stdc++.h>
#define NMAX 801
using namespace std;
ifstream in("nrtri.in");
ofstream out("nrtri.out");
int main() {
int n, v[NMAX];
in >> n;
// citim lungimile bețișoarelor
for (int i = 0; i < n; ++i)
in >> v[i];
// sortăm ca să putem aplica regula v[i] + v[j] >= v[k]
sort(v, v + n);
long long cnt = 0;
// alegem primul bețișor al tripletului
for (int i = 0; i < n - 2; ++i)
// alegem al doilea bețișor
for (int j = i + 1; j < n - 1; ++j) {
int s = v[i] + v[j]; // maximul permis pentru v[k]
// căutăm cu binary search cel mai mare k cu v[k] ≤ s
int low = j + 1, high = n - 1, r = j;
while (low <= high) {
int mid = low + (high - low) / 2;
if (v[mid] <= s){
r = mid; // mid poate forma triunghi
low = mid + 1; // căutăm mai la dreapta
}
else
high = mid - 1; // prea mare, mergem la stânga
}
// pentru (i, j) numărul de k valide este (r - j)
cnt += (r - j);
}
out << cnt;
return 0;
}