Cod sursa(job #1124769)

Utilizator catalincraciunCraciun Catalin catalincraciun Data 26 februarie 2014 13:41:34
Problema Numarare triunghiuri Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.1 kb
/// 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;
}