POJ 3714 Raid (最近點對)感覺數據怪怪的

傳送門

題目大意就是要你從兩組點鐘選出距離最小的兩點,輸出他們的距離。
一道經典最小點對問題+模板

我看了晚上很多人的代碼,這題交的時候感覺怪怪的
比如G++wa , C++ac這類情況

我的代碼也是用c++才能ac

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#define LL __int64
using namespace std;

const int maxn = 100100;

struct point
{
    double x,y;
    int flag;
};

point p[2*maxn],tmp[maxn];

double dis(point p1,point p2)
{
    if(p1.flag!=p2.flag){
        return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
    }else return 1e50;
}

bool cmp(point a,point b)
{
    return a.x<b.x;
}

bool cmpy(point a,point b)
{
    return a.y<b.y;
}

double solve(int l,int r)
{
    if(l==r) return 1e50;
    if(l+1==r) return dis(p[l],p[r]);
    int mid = (l+r)>>1;
    double d = min(solve(l,mid),solve(mid+1,r));

    int cnt = 0;
    for(int i=l;i<=r;i++){
        if(fabs(p[i].x - p[mid].x)<d) tmp[cnt++] = p[i];
    }

    sort(tmp,tmp+cnt,cmpy);//網上一般是左右搜,我覺得沒必要


    for(int i = 0;i<cnt;i++){
        for(int j=i+1;j<cnt;j++){
            if(fabs(tmp[i].y - tmp[j].y) >= d) continue;
            d = min(dis(tmp[i],tmp[j]),d);
        }
    }
    return d;
}

int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
            p[i].flag = 0;
        }
        for(int i=n;i<n*2;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
            p[i].flag = 1;
        }
        n <<= 1;
        sort(p,p+n,cmp);
        double mindis = solve(0,n-1);
        printf("%.3lf\n",mindis);//如果是%.3f的話g++c++都能過,lf只能過c++

    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章