Cod sursa(job #2071734)

Utilizator mamamea132Pronoza Cristian-Valentin mamamea132 Data 20 noiembrie 2017 22:38:27
Problema Cele mai apropiate puncte din plan Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.22 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
struct punct{
    int x,y;
};
struct dist{
    punct A,B;
    float distanta=0;
};
void citire(vector<punct> &puncte)
{
    ifstream in("cmap.in");
    int nr;
    in>>nr;
    punct dummy;
    while(in>>dummy.x>>dummy.y)
        puncte.push_back(dummy);
    in.close();
}
float distanta(punct A,punct B)
{
    return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
int comparator(punct A,punct B)
{
    return A.x<B.x;
}
int comparatorY(punct A,punct B)
{
    return A.y<B.y;
}
dist min(dist A,dist B)
{
    if(A.distanta<B.distanta) return A;
    else return B;
}

void distantaMerged(int left, int m, int right, vector<punct> &puncte, dist &minima, punct mijloc)
{
    vector<punct> aux;
    vector<punct> bandaDistMin;
    int iL=left;
    int iR=m+1;
    int nrElementeL=m-left+1;
    int nrElementeR=right-m;
    while(nrElementeR&&nrElementeL)
    {
        if(puncte[iL].y<puncte[iR].y)
        {
            if(distanta(mijloc,puncte[iL])<minima.distanta)  bandaDistMin.push_back(puncte[iL]);
            aux.push_back(puncte[iL]);
            iL++;
            nrElementeL--;
        }
        else
        {
            if(distanta(mijloc,puncte[iR])<minima.distanta)  bandaDistMin.push_back(puncte[iR]);
            aux.push_back(puncte[iR]);
            iR++;
            nrElementeR--;
        }
    }
    if(nrElementeR)
    {
        while(nrElementeR)
        {
            if(distanta(mijloc,puncte[iR])<minima.distanta) bandaDistMin.push_back(puncte[iR]);
            aux.push_back(puncte[iR]);
            iR++;
            nrElementeR--;
        }
    }
    else
    {
        while(nrElementeL)
        {
            if(distanta(mijloc,puncte[iL])<minima.distanta)  bandaDistMin.push_back(puncte[iL]);
            aux.push_back(puncte[iL]);
            iL++;
            nrElementeL--;
        }
    }
    for(int i=left;i<=right;i++)
    {
        puncte[i]=aux[i-left];
    }
    for(int i=0;i<bandaDistMin.size()-1;i++)
    {
        for(int j=i+1;j<bandaDistMin.size()&&j<i+8;j++)
            if(distanta(bandaDistMin[i],bandaDistMin[j])<minima.distanta&&distanta(bandaDistMin[i],bandaDistMin[j])!=0)
            {
                minima.distanta=distanta(bandaDistMin[i],bandaDistMin[j]);
                minima.A=bandaDistMin[i];
                minima.B=bandaDistMin[j];
            }
    }
}
dist distantaMinima(int left,int right,vector<punct> &puncte)
{
    if(right-left==1)
    {
        if(puncte[left].y>puncte[right].y)
        {
            punct aux=puncte[left];
            puncte[left]=puncte[right];
            puncte[right]=aux;
        }
        dist x;
        x.A=puncte[left];x.B=puncte[right];x.distanta=distanta(puncte[left],puncte[right]);
        return x;
    }
    else
        if(right-left==2)
        {
            sort(puncte.begin()+left,puncte.begin()+right,comparatorY); //3 elemente
            dist x;
            float d1=distanta(puncte[left],puncte[left+1]);
            float d2=distanta(puncte[left+1],puncte[right]);
            float d3=distanta(puncte[left], puncte[right]);
            if(d1<=d2&&d1<=d3)  {x.A=puncte[left];x.B=puncte[left+1];x.distanta=d1;}
            if(d2<=d1&&d2<=d3)  {x.A=puncte[left+1];x.B=puncte[right];x.distanta=d2;}
            if(d3<=d2&&d3<=d1)  {x.A=puncte[left];x.B=puncte[right];x.distanta=d3;}
            return x;
        }
        else
        {
            int m=(left+right)/2;
            punct mijloc=puncte[m];
            dist x=min(distantaMinima(left,m,puncte),distantaMinima(m+1,right,puncte));
            distantaMerged(left,m,right,puncte,x,mijloc);
            return x;
        }
}
int main()
{
    vector<punct> puncte;
    citire(puncte);
    sort(puncte.begin(),puncte.end(),comparator);
    dist result=distantaMinima(0,puncte.size()-1,puncte);
    cout<<result.A.x<<" "<<result.A.y<<" si "<<result.B.x<<" "<<result.B.y<<" cu distanta:"<<result.distanta<<endl;
    //for(int i=0;i<puncte.size();i++)
       // cout<<puncte[i].x<<" "<<puncte[i].y<<endl;
    ofstream out("cmap.out");
    out<<result.distanta;
    return 0;
}