• luogu P1429 平面最近点对


    传送门 

    调半个晚上...一个板子整这么慢

    之前网上一直没看明白 今天终于完事了

    首先分治很容易想到 这里按x分

    考虑暴力的复杂度极限 就是所有的点到中线距离相等

    可以看出上下相距很远的点显然不对

    那么这个很远是什么呢 是不是大于当前答案d的都可以舍去..

    所以我们可以对于到中线的距离小于d的每个点找到与它y轴距离小于d的点更新答案(主要是因为画个圆太麻烦了)

    然后这个可以证明每个点匹配的个数是常数 就需要用到网上流传的那个图了

    至于为什么可以考虑如果一侧的d*d正方形里如果有四个以上的点那么最小值一定可以更小

    代码真好写...

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<queue>
     6 #include<iostream>
     7 #define ms(a,b) memset(a,b,sizeof a)
     8 #define rep(i,a,n) for(int i = a;i <= n;i++)
     9 #define per(i,n,a) for(int i = n;i >= a;i--)
    10 #define inf 2147483647
    11 using namespace std;
    12 typedef long long ll;
    13 ll read() {
    14     ll as = 0,fu = 1;
    15     char c = getchar();
    16     while(c < '0' || c > '9') {
    17         if(c == '-') fu = -1;
    18         c = getchar();
    19     }
    20     while(c >= '0' && c <= '9') {
    21         as = as * 10 + c - '0';
    22         c = getchar();
    23     }
    24     return as * fu;
    25 }
    26 const int N = 200003;
    27 //head
    28 typedef double D;
    29 #define eps 1e-8
    30 struct node {
    31     D x,y;
    32     D len() {return sqrt(x*x+y*y);}
    33     node operator - (const node &o) const {
    34         return (node){x-o.x,y-o.y};
    35     }
    36     bool operator < (const node &o) const {
    37         return x < o.x;
    38     }
    39 }p[N];
    40 int n;
    41 
    42 //[l,r)
    43 D solve(int l,int r) {
    44     if(r - l == 1) return 3e20;
    45     int m = l+r >> 1;
    46     D xmid = (p[m].x + p[m - 1].x) / 2.0;
    47     D d = min(solve(l,m),solve(m,r));
    48     int topb = 0,topc = 0;
    49     static node a[N],b[N],c[N];
    50     int L = l,R = m;
    51     int curb = 0,curc = 0;
    52     rep(i,l,r - 1) {
    53         if(L < m && (R == r || p[L].y < p[R].y) ) {
    54             a[i] = p[L++];
    55             if(xmid - a[i].x < d) b[topb++] = a[i];
    56         } else {
    57             a[i] = p[R++];
    58             if(a[i].x - xmid < d) c[topc++] = a[i];
    59         }
    60     }
    61 
    62     rep(i,l,r - 1) p[i] = a[i];
    63     while(curb < topb || curc < topc) {
    64         if(curb < topb && (curc == topc || b[curb].y < c[curc].y)) {
    65             per(k,curc - 1,0) {
    66                 if(b[curb].y - c[k].y > d) break;
    67                 d = min(d,(c[k] - b[curb]).len());
    68             }
    69             curb++;
    70         } else {
    71             per(k,curb - 1,0) {
    72                 if(c[curc].y - b[k].y > d) break;
    73                 d = min(d,(b[k] - c[curc]).len());
    74             }
    75             curc++;
    76         }
    77     }
    78     return d;
    79 }
    80 
    81 int main() {
    82     n = read();
    83     rep(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);
    84     sort(p+1,p+n+1);
    85     printf("%.4f
    ",solve(1,n+1));
    86     return 0;
    87 }
  • 相关阅读:
    让flask在出现语法错误时仍然自动重启
    ubuntu配置zsh和oh-my-zsh
    docker运行python3.6+flask小记
    vscode python3 配置生成任务
    从flask视角理解angular(四)Route
    从flask视角理解angular(三)ORM VS Service
    从flask视角理解angular(二)Blueprint VS Component
    从flask视角学习angular(一)整体对比
    Linux高级变量
    linux系统中查看日志及系统信息
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/10034275.html
Copyright © 2020-2023  润新知