zoukankan      html  css  js  c++  java
  • UVa 10245 The Closest Pair Problem 分治

    题意:

    给出平面上的n个点,求最近点对的距离。

    分析:

    我们可以先把点从左到右排序,然后以中间的点为界,将点分为左右两个部分。
    假设我们左右两部分得到的最近点对的距离为d,那么我们要检查是否有跨越分界线并且距离小于d的点对。
    首先这两个点的到分割线的距离不能超过d,而且这两个点的纵坐标之差的绝对值也不能超过d。
    因此需要检查的点对就很少了。

    每次递归完,我们按照y坐标从小到大归并排序,这样对于一个点(p_i),只要检查y坐标比(p_i)小的那些点就行了。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    using namespace std;
    
    const int maxn = 10000 + 10;
    const double INF = 1e5;
    
    struct Point
    {
    	double x, y;
    
    	void read() { scanf("%lf%lf", &x, &y); }
    
    	bool operator < (const Point& t) const {
    		return x < t.x || (x == t.x && y < t.y);
    	}
    };
    
    bool cmp(Point a, Point b) { return a.y < b.y; }
    
    int n;
    Point p[maxn];
    
    double solve(Point* a, int n) {
    	if(n <= 1) return INF;
    	int m = n / 2;
    	double x = a[m].x;
    	double d = min(solve(a, m), solve(a + m, n - m));
    	inplace_merge(a, a + m, a + n, cmp);
    
    	vector<Point> b;
    	for(int i = 0; i < n; i++) {
    		if(fabs(a[i].x - x) >= d) continue;
    		for(int j = b.size() - 1; j >= 0; j--) {
    			double dx = a[i].x - b[j].x;
    			double dy = a[i].y - b[j].y;
    			if(dy >= d) break;
    			d = min(d, sqrt(dx * dx + dy * dy));
    		}
    		b.push_back(a[i]);
    	}
    
    	return d;
    }
    
    int main()
    {
    	while(scanf("%d", &n) == 1 && n) {
    		for(int i = 0; i < n; i++) p[i].read();
    		sort(p, p + n);
    		double ans = solve(p, n);
    		if(ans >= 10000.0) puts("INFINITY");
    		else printf("%.4f
    ", ans);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    Kotlin扩展深入解析及注意事项和可见性
    Kotlin属性揭秘与延迟初始化特性
    Kotlin伴生对象及其字节码内幕详解
    Kotlin继承与重写重要特性剖析
    Kotlin构造方法详解与初始化过程分析
    Range与面向对象的Kotlin
    Kotlin编译器优化与when关键字详解
    Kotlin基础特性深入讲解
    java读取mysql表的注释及字段注释
    mysql导入导出sql文件
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/5231800.html
Copyright © 2011-2022 走看看