Pagini recente » Cod sursa (job #350028) | Cod sursa (job #430060) | Cod sursa (job #355330) | Cod sursa (job #2911544) | Cod sursa (job #1124769)
/// Craciun Catalin
/// Nrtri
/// Cautare binara
/// www.infoarena.ro/problema/nrtri
#include <fstream>
#include <iostream>
#define NMax 850
#define sizeMax 800000
using namespace std;
ifstream f("nrtri.in");
ofstream g("nrtri.out");
int n;
int A[NMax];
char intrare[sizeMax], *pointerTo=intrare;
long long tri=0;
int i,j;
void mergeSort(int left, int mij, int right)
{
int B[NMax];
int copyLeft=left;
int copyMij=mij+1;
int poz=1;
while (copyLeft<=mij && copyMij<=right)
if (A[copyLeft]<A[copyMij])
B[poz++]=A[copyLeft++];
else
B[poz++]=A[copyMij++];
while (copyLeft<=mij)
B[poz++]=A[copyLeft++];
while (copyMij<=right)
B[poz++]=A[copyMij++];
int auxP=left;
for (int i=1;i<poz;i++, auxP++)
A[auxP]=B[i];
}
void divide(int left, int right)
{
if (left<right)
{
int mij=(left+right)/2;
divide(left, mij);
divide(mij+1, right);
mergeSort(left, mij, right);
}
}
void cautBin(int left, int right)
{
int mij=(left+right)/2;
while (left<=right)
{
int mij=(left+right)/2;
if (A[mij]<=A[i]+A[j] && !(A[mij]+A[i]>=A[j] && A[mij]+A[j]>=A[i]))
{
/// A[mij] este prea mic
left=mij+1;
}
else if (A[i]+A[j]<A[mij])
{
/// A[mij] este prea mare
right=mij-1;
}
else if (A[i]+A[j]>=A[mij] && A[mij]+A[i]>=A[j] && A[mij]+A[j]>=A[i])
{
/// Este indeplinita conditia de triunghi
tri++;
int auxMij=mij+1;
while (A[i]+A[j]>=A[mij] && A[mij]+A[i]>=A[j] && A[mij]+A[j]>=A[i] && mij<right)
{
mij++;
if (A[i]+A[j]>=A[mij] && A[mij]+A[i]>=A[j] && A[mij]+A[j]>=A[i])
tri++;
}
mij=auxMij-2;
while (A[i]+A[j]>=A[mij] && A[mij]+A[i]>=A[j] && A[mij]+A[j]>=A[i] && mij>left)
{
mij--;
if (A[i]+A[j]>=A[mij] && A[mij]+A[i]>=A[j] && A[mij]+A[j]>=A[i])
tri++;
}
break;
}
}
}
inline int atoi()
{
int x=0;
for (;!(*pointerTo>='0' && *pointerTo<='9'); ++pointerTo);
for (; (*pointerTo>='0' && *pointerTo<='9'); ++pointerTo)
x=x*10+(*pointerTo-'0');
return x;
}
void parcurgere()
{
if (n<=150)
{
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++)
for (int k=j+1;k<=n;k++)
if (A[i]+A[j]>=A[k] && A[j]+A[k]>=A[i] && A[i]+A[k]>=A[j])
tri++;
}
else
{
divide(1,n);
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++)
cautBin(j+1, n);
}
g<<tri<<'\n';
g.close();
}
void citire()
{
/// Citire optimizata cu atoi
f.read(intrare, sizeMax);
n=atoi();
for (int i=1;i<=n;i++)
A[i]=atoi();
}
int main()
{
citire();
parcurgere();
return 0;
}