• 最近点对算法模板


    #include<algorithm>
    using namespace std;
    #define maxs 200005
    struct Point
    {
        double x,y;
    }point[maxs];
    int y_sort[maxs];
    int cmpx(Point a,Point b)//按照x对这些点从小到大排序
    {
        return a.x<b.x;
    }
    int cmpy(int a,int b)//对最近点算法中的y_sort数组排序
    {
        return point[a].y<point[b].y;
    }
    double dis(Point a,Point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    /*
        最近点对算法,在point[first]--point[last]个点中寻找一个最短距离
        使用该算法前先对这些点排序
        sort(point,point+n,cmpx);
    */
    double findMin(int first, int last)
    {
        if((last-first)==1)
            return dis(point[first],point[last]);
        else if(last-first==2)
        {
            double d1 = dis(point[first],point[first+1]);
            double d2 = dis(point[first],point[first+2]);
            double d3 = dis(point[first+1],point[first+2]);
            return min(min(d1,d2),d3);
        }
        //二分
        int mid = (first+last)/2;
        double min_dist = min(findMin(first,mid),findMin(mid+1,last));
        if(min_dist==0)
            return 0;
        int y_end = 0;
        for(int i=mid;point[mid].x-point[i].x<min_dist&&i>=first;i--)
            y_sort[y_end++]=i;
        for(int i=mid+1;point[i].x-point[mid+1].x<min_dist&&i<=last;i++)
            y_sort[y_end++]=i;
        sort(y_sort,y_sort+y_end,cmpy);
        for(int i=0;i<y_end;i++)
            for(int j=i+1;j<y_end&&(point[y_sort[j]].y-point[y_sort[i]].y)<min_dist;j++)
                min_dist=min(min_dist,dis(point[y_sort[i]],point[y_sort[j]]));
        return min_dist;
    
    }
    

    poj3714

    题目大意:

    有若干车站和加油站,求车站和加油站的最小距离.

    思路:

    求最近点对,注意的是需要对车站和加油站分类,同类的话就初始化为INF

    这样就不会找到相同类间的距离了,从而只会得到车站和加油站的最小距离

    #include <iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define maxs 200005
    #define INF 1e100
    struct Point
    {
        double x,y;
        bool flag;
    }point[maxs];
    int y_sort[maxs];
    int cmpx(Point a,Point b)//按照x对这些点从小到大排序
    {
        return a.x<b.x;
    }
    int cmpy(int a,int b)//对最近点算法中的y_sort数组排序
    {
        return point[a].y<point[b].y;
    }
    double dis(Point a,Point b)
    {
        if(a.flag!=b.flag)
            return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
        return INF;//是同一类,初始化为无穷大,这样最近点对算法就不会找同类的最短距离
    }
    /*
        最近点对算法,在point[first]--point[last]个点中寻找一个最短距离
        使用该算法前先对这些点排序
        sort(point,point+n,cmpx);
    */
    double findMin(int first, int last)
    {
        if((last-first)==1)
            return dis(point[first],point[last]);
        else if(last-first==2)
        {
            double d1 = dis(point[first],point[first+1]);
            double d2 = dis(point[first],point[first+2]);
            double d3 = dis(point[first+1],point[first+2]);
            return min(min(d1,d2),d3);
        }
        //二分
        int mid = (first+last)/2;
        double min_dist = min(findMin(first,mid),findMin(mid+1,last));
        if(min_dist==0)
            return 0;
        int y_end = 0;
        for(int i=mid;point[mid].x-point[i].x<min_dist&&i>=first;i--)
            y_sort[y_end++]=i;
        for(int i=mid+1;point[i].x-point[mid+1].x<min_dist&&i<=last;i++)
            y_sort[y_end++]=i;
        sort(y_sort,y_sort+y_end,cmpy);
        for(int i=0;i<y_end;i++)
            for(int j=i+1;j<y_end&&(point[y_sort[j]].y-point[y_sort[i]].y)<min_dist;j++)
                min_dist=min(min_dist,dis(point[y_sort[i]],point[y_sort[j]]));
        return min_dist;
    
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T,n;
        cin>>T;
        while(T--)
        {
            scanf("%d",&n);
            for(int i=0;i<n;i++)
            {
                scanf("%lf%lf",&point[i].x,&point[i].y);
                point[i].flag=true;
            }
            for(int i=n;i<2*n;i++)
            {
                scanf("%lf%lf",&point[i].x,&point[i].y);
                point[i].flag=false;
            }
            n=2*n;
            sort(point,point+n,cmpx);//排序
            double ans = findMin(0,n-1);
            printf("%0.3f
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    字符串样式效果
    javaScript 继承原型链
    javaScript 的继承,call()
    二维数组中的查找
    如何证明一个映射是混沌的。
    netty如何知道连接已经关闭,socket心跳,双工?异步?
    java中线程安全的map是ConcurrentHashMap
    failed to load class "org.sl4j.impl.StaticLoggerBinder"
    Tcp端口以及端口相关协议详解
    Tcp的三次握手,以及原理详解
  • 原文地址:https://www.cnblogs.com/wt20/p/5803349.html
Copyright © 2020-2023  润新知