求助 哭辽

P1429 平面最近点对(加强版)

Dark_X @ 2019-11-07 10:32:57

为什么我将线两边的点按照纵坐标升序排序

之后如果有一个不合法(大于val)

就直接break掉 但是错了 而换成continue就对了

说不明白还是放代码吧

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define d double
#define N 200200
using namespace std;

const int inf=0x3f3f3f3f;
int n;
struct mes{
    d x,y;
}m[N];
struct temp{
    d xi,yi;
}t[N];

inline bool comp(mes a,mes b){
    return a.x<b.x;
}

inline bool cmp(temp a,temp b){
    return a.yi<b.yi;
}

inline d calc(d x1,d y1,d x2,d y2){
    return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}

inline d merge(int l,int r){
    d val=inf;
    if(l>=r) return val;
    if(l+1==r) return calc(m[l].x,m[l].y,m[r].x,m[r].y);
    int mid=(l+r)>>1;
    val=min(val,min(merge(l,mid),merge(mid+1,r)));
    int cnt=0;
    for(int i=l;i<=r;++i)
        if(fabs(m[i].x-m[mid].x)<=val) t[++cnt].xi=m[i].x,t[cnt].yi=m[i].y;
    sort(t+1,t+1+cnt,cmp);
    for(int i=1;i<=cnt;++i)
        for(int j=1;j<=cnt;++j){
            if(i==j||fabs(t[j].yi-t[i].yi)>val) continue;
            //if(fabs(t[j].yi-t[i].yi)>val) break;
            val=min(val,calc(t[i].xi,t[i].yi,t[j].xi,t[j].yi));
        }
    return val;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%lf%lf",&m[i].x,&m[i].y);
    sort(m+1,m+1+n,comp);
    printf("%.4lf",merge(1,n));
    return 0;
}

by hkr04 @ 2019-11-07 11:03:58

把j从i+1开始枚举不好吗,这样不用fabs,也可以直接break
不能直接break是因为比你小的绝对值会变小啊……


by Clearlove7loveyou @ 2019-11-07 11:38:45

tql


|