zoukankan      html  css  js  c++  java
  • 算法导论之最近顶点对

    算法导论在计算几何学这章给出了最近顶点对的求法:采用典型的分治算法

    (1)分解:将所有顶点按照x坐标排序后大致分为俩个大小相等的集合L和R

    (2)求解:分别求出L和R集合中的最小具体,并取二者的较小值为当前的最小值ans

    (3)合并:对于分属于两个集合的点,每次各取出一个点,计算两点的距离,每次与ans比较去较小值来更新ans的值,并且可以进行优化,具体的优化步骤一共有3个,具体见算法导论。

    算法的运行时间为O(n log n),具体代码如下:

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    int const MAX_N = 100005;
    struct Point{
    	double x, y;
    };
    
    Point p[MAX_N];
    int yy[MAX_N];
    
    bool cmpx(Point const& pa, Point const& pb)
    {
    	return pa.x < pb.x;
    }
    
    bool cmpy(int const& a, int const& b)
    {
    	return p[a].y < p[b].y;
    }
    
    inline double dis(Point const& pa, Point const& pb)
    {
    	return sqrt((pa.x - pb.x) * (pa.x - pb.x) + (pa.y - pb.y) * (pa.y - pb.y));
    }
    
    inline double min(double const& a, double const& b)
    {
    	return a < b ? a : b;
    }
    
    double closeset(int low, int high)
    {
    	if(low + 1 == high)
    	{
    		return dis(p[low], p[high]);
    	}
    	if(low + 2 == high)
    	{
    		return min(dis(p[low], p[high]), min(dis(p[low], p[low + 1]), dis(p[low + 1], p[high])));
    	}
    
    	int mid = (low + high) >> 1;
    
    	double ans = min(closeset(low, mid), closeset(mid + 1, high));
    
    	int cnt = 0;
    	for(int i = low; i <= high; i++)
    	{
    		if(p[i].x > p[mid].x - ans && p[i].x < p[mid].x + ans)
    		{
    			yy[cnt++] = i;
    		}
    	}
    
    	sort(yy, yy + cnt, cmpy);
    
    	for(int i = 0; i < cnt; i++)
    	{
    		int k = (i + 7) > cnt ? cnt : (i + 7);
    		for(int j = i + 1; j < k; j++)
    		{
    			if(p[yy[j]].y - p[yy[j]].y >= ans)
    				break;
    			ans = min(ans, dis(p[yy[j]], p[yy[i]]));
    		}
    	}
    	return ans;
    }
    
    int main()
    {
    	//freopen("min.txt", "r", stdin);
    	int n, i;
    	while(scanf("%d", &n) != EOF)
    	{
    		if(!n)
    			break;
    		for(i = 0; i < n; i++)
    		{
    			scanf("%lf %lf", &p[i].x, &p[i].y);
    		}
    		sort(p, p + n, cmpx);
    		double ans = closeset(0, n - 1);
    		printf("%.2lf
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    第四章 分布式扩展
    第三章 2.性能压测,容量问题
    第三章 1.云部署,打包上传
    MySQL语法大全
    Python随手记
    Python操作Mysql中文乱码问题
    Python基础函数
    破解电信校园网路由限制
    ThinkPHP扩展函数的三个方法
    $_SERVERS预定义变量
  • 原文地址:https://www.cnblogs.com/wwblog/p/3948092.html
Copyright © 2011-2022 走看看