Cod sursa(job #2070920)

Utilizator doodling19Diana Diac doodling19 Data 20 noiembrie 2017 00:34:05
Problema Cele mai apropiate puncte din plan Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.69 kb
#include <iostream>
#include<vector>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<limits>
#include <iomanip>
using namespace std;


ifstream f("cmap.in");
ofstream g("cmap.out");

struct punct
{
    int x,y;
};

bool compara(punct i, punct j)
{
    return (i.x<j.x);
}

bool comparaY(punct i, punct j)
{
    return (i.y<j.y);
}

long long distanta(punct i, punct j)
{
    cout<<"i.x: "<<i.x<<"i.y: "<<i.y<<"j.x: "<<j.x<<"j.y: "<<j.y<<endl;
     long long dx = (1LL*(i.x - j.x));
     long long dy = (1LL*(i.y - j.y));
    cout<<"d: "<<dx*dx + dy*dy<<endl;
    return dx*dx + dy*dy;
}

long double distMinVector (int stg, int dr, vector<punct> v)//(dr-stg+1)^2 complexitatea
{
    //atinge dreapta!
    double dmin = distanta(v[stg],v[stg+1]);
    double d;
    for(int i=stg; i<dr; i++)
    {
        for(int j=i+1; j<=dr; j++)
        {
            d = distanta(v[i],v[j]);
            if(dmin > d)
                dmin = d;
        }
    }
    // cout<<dmin<<endl;
    return dmin;
}

void citire(int &n, vector<punct> &v)
{
    punct z;
    f>>n;
    for(int i=0; i<n; i++)
    {
        f>>z.x>>z.y;
        v.push_back(z);
    }
    cout<<"n= "<<n<<endl;
}


double divide(int n,int S, int D, vector<punct> X)
{
    punct p1,p2;
    /*if(n<=3)prea mult timp
    {
        return distMinVector(0,n-1,X);
    }*/
    cout<<"D: "<<D<<" S: "<<S<<endl;
    if( D-S == 1)
        return distanta( X[S], X[D] );

    if ( D-S == 2 )
        {
            return min(distanta(X[S], X[S+1]),min(distanta(X[S+1], X[D]),distanta(X[S], X[D])));
        }
    int mij = (S+D)/2;
    //stapaneste
    long long distStg = divide(mij,S,mij,X);//nu contine si mijlocul
    long long distDr = divide(n-mij+1,mij+1,D,X);//contine si mijlocul
    //stop stapaneste
    //Combina/Cucereste
    long long dist = min(distStg,distDr);
    cout<<"dist1 = "<<dist<<endl;
    long long rad_dist = ceil(sqrt(dist));//salveaza timp, fereste de nan
    vector<punct> sirY;//contine toate punctele ce sunt la o distanta de cel mult dist de dreapta din mijloc si se sorteaza dupa Y
    int j=0;
    for(int i=S; i<=D; i++) //adaug punctele cu distanta cel mult dist
    {
        if(abs(X[i].x-X[mij].x)<=rad_dist)
        {
            sirY.push_back(X[i]);
            j++;
        }
    }
    //sortez
    sort(sirY.begin(),sirY.end(),comparaY);
    //pt fiecare punct p din sirY cauta in primele 7 puncte care dintre ele sunt la distanta de cel mult dist fata de p
    long long dmin2=dist;//maximul
    int N = (int)sirY.size();
    for(int i=0; i<N; i++)
    {
        long long d1;
        //cout<<endl;
        for(int k=i+1; k<=(i+7)&&k<N; k++)
        {
            //cout<<"1 ";
            //d1 = distanta(X[i],X[k]);
            if((sirY[k].y-sirY[i].y)<=dist)
            {
                d1 = distanta(sirY[i],sirY[k]);
                if(dmin2>d1)
                {
                    dmin2=d1;
                    p1 = sirY[i];
                    p2=sirY[k];
                }
            }

        }
        // cout<<endl;
    }
    cout<<"dist = "<<min(dist,dmin2)<<endl;
    return min(dist,dmin2);
}

void lucreaza(int n, vector<punct> &v)
{
    //ordonez v dupa x
    cout<<"n1= "<<n<<endl;
    sort(v.begin(),v.end(),compara);
    // cout<<"Vectorul ordonat dupa x: \n";
    /* for(int i=0; i<n; i++)
     {
         cout<<v[i].x<<" "<<v[i].y<<endl;
     }*/
    cout<<"Distanta minima este: "<< setprecision (6)<<sqrt(divide(n,0,n-1,v));
    //g<< setprecision (9)<<divide(n,0,n-1,v);

}

int main()
{
    int n;//nr de puncte
    vector<punct> v;
    citire(n,v);
    lucreaza(n,v);

    return 0;
}