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;
    }
    
  • 相关阅读:
    最全的常用正则表达式大全
    服务器调用JS
    ASP-----分页功能的实现
    流操作text文件------读取、保存文档
    linq to sql 增删改查
    数据库的高级应用
    SQL---------表的约束
    面向对象--继承练习
    Winform---文件夹操作
    面向对象--里氏转换练习
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/5231800.html
Copyright © 2011-2022 走看看