poj3714 Raid(分治求平面最近点对)

题目链接:https://vjudge.net/problem/POJ-3714

题意:给定两个点集,求最短距离。

思路:在平面最近点对基础上加了个条件,我么不访用f做标记,集合1的f为1,集合2的f为-1,那么求两个点的距离时,如果a.f*b.f=-1时计算距离,否则乘积为1的话返回inf。其它就和hdoj1007一样了.

AC代码:

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;

const int maxn=2e5+5;
const double inf=1e30;
int T,n,cnt,id[maxn];
struct node{
    int x,y,f;
}pt[maxn];

bool operator < (const node& a,const node& b){
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

bool cmp(int a,int b){
    return pt[a].y<pt[b].y;
}

double dist(const node& a,const node& b){
    if(a.f*b.f==1) return inf;
    return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
}

double fenzhi(int l,int r){
    double d=inf;
    if(l==r) return d;
    if(l+1==r) return dist(pt[l],pt[r]);
    int mid=(l+r)>>1;
    d=min(fenzhi(l,mid),fenzhi(mid+1,r));
    cnt=0;
    int t1,t2,l1=l,r1=mid,mid1;
    while(l1<=r1){
        mid1=(l1+r1)>>1;
        if(pt[mid].x-pt[mid1].x<d) r1=mid1-1;
        else l1=mid1+1;
    }
    t1=l1;
    l1=mid+1,r1=r;
    while(l1<=r1){
        mid1=(l1+r1)>>1;
        if(pt[mid1].x-pt[mid].x<d) l1=mid1+1;
        else r1=mid1-1;
    }
    t2=r1;
    for(int i=t1;i<=t2;++i)
            id[++cnt]=i;
    sort(id+1,id+cnt+1,cmp);
    for(int i=1;i<cnt;++i)
        for(int j=i+1;j<=cnt&&(pt[id[j]].y-pt[id[i]].y<d);++j)
            d=min(d,dist(pt[id[i]],pt[id[j]]));
    return d;
}

int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=2*n;++i){
            scanf("%d%d",&pt[i].x,&pt[i].y);
            if(i<=n) pt[i].f=1;
            else pt[i].f=-1;
        }
        sort(pt+1,pt+1+2*n);
        printf("%.3f\n",fenzhi(1,2*n));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/FrankChen831X/p/11411688.html

时间: 2024-10-13 14:04:47

poj3714 Raid(分治求平面最近点对)的相关文章

牛客练习赛11 B trie树+拓扑判环 E 分治求平面最近点对

牛客练习赛11 B  假的字符串题意:给定n个字符串,互不相等,你可以任意指定字符之间的大小关系(即重定义字典序),求有多少个串可能成为字典序最小的串,并输出它们. tags:好题 对于一个字符串, 1]如有其它字符串是它的前缀,那肯定不可能.这个直接用字典树处理就可以. 2]但如果以这个字符串为最小,怎么判定其它字符串不会矛盾呢? 其实矛盾的情况详细一点说是: 比如要以  abcd 为最小, 但又有另一个字符串 aba ,这就矛盾了. 对这种情况,在跑字典树的时候,我们对有相同父亲结点的多个儿

POJ 3714 分治/求平面最近点对

第一次见这种问题直接懵圈...没想到分治法这么强大,借鉴了lyd的代码: 代码如下 #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<iostream> using namespace std; const int maxn=200010; struct point{ int x,y,z; }; point a[maxn],b[maxn]

求平面最近点对(分治与递归,注:最远点对用凸包求)

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 36793    Accepted Submission(s): 9552 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat

poj 3714 Raid 分治法求平面最近点对

题意: 给平面上的n个点,求两点间的最短距离. 分析: 分治法,保存点用vector会tle... 代码: //poj 3714 //sep9 #include <iostream> #include <algorithm> #include <cmath> using namespace std; const double INF=1e50; struct P { double x,y; int type; }p[240000],b[240000]; bool cmp

POJ3714:求平面最近点对

寻找两个集合中的点的最近点对 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const double oo=1e50; 7 int n; 8 double ab(double x) 9 { 10 return x>0?x:-x; 11 } 12 struct node 13 { 14 doub

POJ 3714 Raid(平面最近点对)

解题思路: 分治法求平面最近点对,点分成两部分,加个标记就好了. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <iomanip>

HDU1007--Quoit Design(平面最近点对)

Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.In the field of Cyberground, the position of each toy is fixed, and the ring is carefull

HDU 5721 Palace BestCoder 2nd Anniversary (平面最近点对)

Palace Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 465    Accepted Submission(s): 118 Problem Description The last trial Venus imposes on Psyche is a quest to the underworld. She is to ta

平面最近点对

HDU 1007 求平面最近点对距离的一半 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; const double eps = 1e-7; const int MAXN = 100010; const double INF = 1e20; struct Point