欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POJ - 3714 Raid(平面最近点对模板题,几何)

程序员文章站 2022-03-02 10:21:12
...

题目链接:点击查看

题目大意:给出两个含有n个点的集合,在两个集合中分别任选一点,使得这两个点之间的距离最小

题目分析:因为n给到了1e5,所以n*n的暴力肯定是不行了,直接从网上copy了个分治优化的模板,时间复杂度为nlogn,可以求出n个点中相距最近的两个点的距离,对于这个题目而言,我们将两个集合中的点分个类,在求距离的时候,若是同类的点,直接返回无穷大即可,这样同类的点肯定不可能是答案了

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;
    
typedef long long LL;
    
const int inf=0x3f3f3f3f;
    
const int N=2e5+100;

struct Point
{
    double x,y;
    bool flag;
}point[N];

int y_sort[N];

int cmpx(Point a,Point b)//按照x对这些点从小到大排序
{
    return a.x<b.x;
}

int cmpy(int a,int b)//对最近点算法中的y_sort数组排序
{
    return point[a].y<point[b].y;
}

double dis(Point a,Point b)
{
	if(a.flag!=b.flag)
    	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    return 1e20;
}
/*
    最近点对算法,在point[first]--point[last]个点中寻找一个最短距离
    使用该算法前先对这些点排序
    sort(point,point+n,cmpx);
*/
double findMin(int first, int last)
{
    if((last-first)==1)
        return dis(point[first],point[last]);
    else if(last-first==2)
    {
        double d1 = dis(point[first],point[first+1]);
        double d2 = dis(point[first],point[first+2]);
        double d3 = dis(point[first+1],point[first+2]);
        return min(min(d1,d2),d3);
    }
    //二分
    int mid = (first+last)/2;
    double min_dist = min(findMin(first,mid),findMin(mid+1,last));
    if(min_dist==0)
        return 0;
    int y_end = 0;
    for(int i=mid;point[mid].x-point[i].x<min_dist&&i>=first;i--)
        y_sort[y_end++]=i;
    for(int i=mid+1;point[i].x-point[mid+1].x<min_dist&&i<=last;i++)
        y_sort[y_end++]=i;
    sort(y_sort,y_sort+y_end,cmpy);
    for(int i=0;i<y_end;i++)
        for(int j=i+1;j<y_end&&(point[y_sort[j]].y-point[y_sort[i]].y)<min_dist;j++)
            min_dist=min(min_dist,dis(point[y_sort[i]],point[y_sort[j]]));
    return min_dist;
}
 
int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--)
	{
		int n;
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%lf%lf",&point[i].x,&point[i].y);
			point[i].flag=true;
		}
		for(int i=n;i<2*n;i++)
		{
			scanf("%lf%lf",&point[i].x,&point[i].y);
			point[i].flag=false;
		}
		sort(point,point+2*n,cmpx);
		printf("%.3f\n",findMin(0,2*n-1));
	}
	
	
	 
	
	
	
	
	
	
        
        
        
        
         
        
    return 0;
}

 

相关标签: 几何