zoukankan      html  css  js  c++  java
  • 最接近点对问题[分治](神他妈的鸽巢原理,别问我,我也不会)

    在二维平面上,有 nn 个点。两点之间的距离,即欧几里得距离,等于

    sqrt{(x_i-x_j)^2+(y_i-y_j)^2}(xi​​xj​​)2​​+(yi​​yj​​)2​​​​

    比如,(1, 3),(4,5)(1,3),(4,5) 两点之间的距离是 sqrt{(1-4)^2+(3-5)^2}=sqrt{13}(14)2​​+(35)2​​​​=13​​。

    在 nn 个点的所有点对中,你需要从中找出一个点对,使得它们之间的距离是最小的。

    输入格式

    第一行一个整数 n (1< n< 100000)n(1n100000)。

    接下来 nn 行,每行两个实数 x,yx,y,表示该点的坐标。

    输出格式

    输出一个实数,即最小的距离值。结果和标准答案之间的误差在 10^{-2}102​​ 以内均被认为是正确的。

    样例输入

    3
    -1.5 0
    0 0
    0 1.5

    样例输出

    1.50

    #include<bits/stdc++.h>
    using namespace std;
    #define M 0x7fffffff
    struct node{
    double x,y;
    }n[100005];
    bool cmp(const node a,const node b){
    if(a.x != b.x)
            return a.x < b.x;
        return a.y < b.y;
    }
    int main()
    {
        int m,i,j;
        cin>>m;
        node q,p;
        for(i=0;i<m;i++){
            cin>>n[i].x>>n[i].y;
        }
        sort(n,n+m,cmp);
        double mid,lmin = M,rmin=M ,mi=M;
        for(i=0;i<m;i++){
            if(n[i].x>=0){
                mid = i;
                break;
            }
        }
        for(i=0;i<mid;i++){
            for(j=i+1;j<i+7&&j<mid;j++){
                double t=pow(n[i].x-n[j].x,2)+pow(n[i].y-n[j].y,2);
            if(t<lmin){
                    lmin = t;
                }
            }
        }
        for(i=mid;i<m;i++){
            for(j=i+1;j<i+7&&j<m;j++){
                double t=pow(n[i].x-n[j].x,2)+pow(n[i].y-n[j].y,2);
            if(t<rmin){
                    rmin = t;;
                }
            }
        }
        double d = min(rmin,lmin);
        for(i=0;i<mid;i++){
            for(j=mid;j<i+7&&j<m;j++){
                    if(n[j].x-n[i].x>d) break;
                    if(n[j].y-n[i].y>d) continue;
                double t=pow(n[i].x-n[j].x,2)+pow(n[i].y-n[j].y,2);
            if(t<mi){
                    mi = t;
                }
            }
        }
        double mt;
        if(lmin<rmin)
            mt = lmin;
            else
            mt = rmin;
        if(mi<mt)
            mt = mi;
        printf("%0.2f",sqrt(mt));
        cout<<endl;
    }
  • 相关阅读:
    titlebar和actionbar上的按钮设置
    Android 实现闹钟功能
    关于禁止ViewPager预加载问题【转】
    RabbitMQ基础概念详细介绍
    Android 使用Android Studio + Gradle 或 命令行 进行apk签名打包
    Android4.0的Alertdialog对话框,设置点击其他位置不消失
    android MediaCodec 音频编解码的实现——转码
    一个android的各种控件库
    golang的验证码相关的库
    android studio提示unable to run mksdcard sdk
  • 原文地址:https://www.cnblogs.com/upstart/p/6767044.html
Copyright © 2011-2022 走看看