首页 > 其他 > 详细

POJ 3714 Raid 最近对点题解

时间:2014-07-02 15:27:40      阅读:483      评论:0      收藏:0      [点我收藏+]

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

那么就增加一个判断,如果是同一个集合中的点,那么就返回最大值,其他和一般的最近对点解法一样。

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

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\n", closest(P, n<<1));
		delete [] P;
	}
	return 0;
}



POJ 3714 Raid 最近对点题解,布布扣,bubuko.com

POJ 3714 Raid 最近对点题解

原文:http://blog.csdn.net/kenden23/article/details/36407517

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!