zoukankan      html  css  js  c++  java
  • POJ 3714 Raid 近期对点题解

    版权声明:本文作者靖心。靖空间地址:http://blog.csdn.net/kenden23/。未经本作者同意不得转载。 https://blog.csdn.net/kenden23/article/details/36407517

    本题是一般近期对点求解,略微添加点限定:有两个集合点,要求不同集合中的点的近期对。

    那么就添加一个推断。假设是同一个集合中的点,那么就返回最大值。其它和一般的近期对点解法一样。

    注意:本题数据有重合点,那么就要防止分类的时候溢出。

    Geeks上的近期对的程序是无法处理有重合点的情况的。


    
    #include <stdio.h>
    #include <stdlib.h>
    #include <float.h>
    #include <math.h>
    #include <algorithm>
    #include <string.h>
    using std::sort;
    struct Point
    {
    	int x, y;
    	int whichSet;
    };
    
    inline int xCmp(const void *a, const void *b)
    {
    	const Point *a1 = static_cast<const Point *>(a);
    	const Point *b1 = static_cast<const Point *>(b);
    	return a1->x - b1->x;
    }
    
    inline int xCmp2(const Point &a, const Point &b)
    {
    	return a.x < b.x;
    }
    
    inline int yCmp2(const Point &a, const Point &b)
    {
    	return a.y < b.y;
    }
    
    inline int yCmp(const void *a, const void *b)
    {
    	const Point *a1 = static_cast<const Point *> (a);
    	const Point *b1 = static_cast<const Point *> (b);
    	return a1->y - b1->y;
    }
    
    inline float dist(Point &a, Point &b)
    {
    	if (a.whichSet == b.whichSet) return FLT_MAX;
    	float xd = (float)(a.x - b.x);
    	float yd = (float)(a.y - b.y);
    	return sqrtf(xd*xd + yd*yd);
    }
    
    float bruteForce(Point P[], int n)
    {
    	float m = FLT_MAX;
    	for (int i = 0; i < n; ++i)
    	{
    		for (int j = i+1; j < n; ++j)
    		{
    			float d = dist(P[i], P[j]);
    			if (d < m) m = d;
    		}
    	}
    	return m;
    }
    
    inline float mMin(float x, float y) { return x < y? x : y; }
    
    float stripClosest(Point strip[], int n, float d)
    {
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = i+1; j < n && strip[j].y -strip[i].y < d; j++)
    		{
    			float t = dist(strip[i], strip[j]);
    			if (t < d) d = t;
    		}
    	}
    	return d;
    }
    
    float closestUtil(Point Px[], Point Py[], int n)
    {
    	if (n <= 3) return bruteForce(Px, n);
    
    	int m = n >> 1;
    	Point midPoint = Px[m];
    
    	Point *PyL = new Point[m+1];
    	Point *PyR = new Point[n-m-1];
    	int le = 0, ri = 0;
    	for (int i = 0; i < n; i++)
    	{//修正bug:添加le<m+1推断,防止反复点。引起溢出
    		if (Py[i].x <= midPoint.x && le < m+1) PyL[le++] = Py[i];
    		else PyR[ri++] = Py[i];
    	}
    
    	float dl = closestUtil(Px, PyL, le);//m+1);
    	float dr = closestUtil(Px+m+1, PyR, ri);//n-m-1);
    
    	float d = mMin(dl, dr);
    
    	Point *strip = new Point[n];
    	int j = 0;
    	for (int i = 0; i < n; i++)
    	{
    		if (fabsf(float(Py[i].x - midPoint.x)) < d) strip[j++] = Py[i];
    	}
    	d = mMin(d, stripClosest(strip, j, d));
    	delete [] strip;
    	delete [] PyL;
    	delete [] PyR;
    	return d;
    }
    
    float closest(Point P[], int n)
    {
    	Point *Px = new Point[n];
    	Point *Py = new Point[n];
    	memcpy(Px, P, n * sizeof(Point));
    	memcpy(Py, P, n * sizeof(Point));
    
    	//qsort(Px, n, sizeof(Point), xCmp);
    	sort(Px, Px+n, xCmp2);
    	//qsort(Py, n, sizeof(Point), yCmp);
    	sort(Py, Py+n, yCmp2);
    
    	float d = closestUtil(Px, Py, n);
    	delete [] Px;
    	delete [] Py;
    	return d;
    }
    
    int main()
    {
    	int T, n;
    	scanf("%d", &T);
    	while (T--)
    	{
    		scanf("%d", &n);
    		Point *P = new Point[n<<1];
    		for (int i = 0; i < n; i++)
    		{
    			scanf("%d %d", &P[i].x, &P[i].y);
    			P[i].whichSet = 1;
    		}
    		for (int i = n; i < (n<<1); i++)
    		{
    			scanf("%d %d", &P[i].x, &P[i].y);
    			P[i].whichSet = 2;
    		}
    		printf("%.3f
    ", closest(P, n<<1));
    		delete [] P;
    	}
    	return 0;
    }



查看全文
  • 相关阅读:
    085 Maximal Rectangle 最大矩形
    084 Largest Rectangle in Histogram 柱状图中最大的矩形
    083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
    082 Remove Duplicates from Sorted List II 有序的链表删除重复的结点 II
    081 Search in Rotated Sorted Array II 搜索旋转排序数组 ||
    080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II
    079 Word Search 单词搜索
    078 Subsets 子集
    bzoj2326: [HNOI2011]数学作业
    bzoj2152: 聪聪可可
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10587859.html
  • Copyright © 2011-2022 走看看