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


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

    另附P1257 平面上的最接近点对

    题目描述

    - 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的
    

    输入格式

    - 第一行:n;2≤n≤200000
      接下来n行:每行两个实数:x y,表示一个点的行坐标和列坐标,中间用一个空格隔开。
    

    输出格式

    - 仅一行,一个实数,表示最短距离,精确到小数点后面4位。
    

    输入 #1

    - 3
      1 1
      1 2
      2 2
    

    输出 #1

    - 1.0000
    

    说明/提示

    - 0<=x,y<=10^9
    

    关于这道题,其实是比较玄学的


    思路很简单(简直就是暴力中的极品

    不知道为什么dalao们说要随机旋转

    我基本上纯暴力A掉了

    以下为方法:

    先求第1个点与其余n-1个点的距离;

    再求第2个点与其余n-2个点的距离;

    …………………………………………

    再求第n-1个点与其余1个点的距离;

    然后找出最小值,如此的算法复杂度为O(n^2)

    核心代码如下:

    
      for(int i=1; i<=n; i++)
            for(int j=i; j<=n; j++)
                if(i+j<=n)
                {
                    d=sqrt((x[i]-x[j])*(x[i]-x[j])*1.0+(y[i]-y[j])*(y[i]-y[j])*1.0);
                    if(d<mindist)	mindist=d;
                }
                
    

    显然不行

    然后就比较玄学

    为了减少枚举量,本少决定只比较每个点后面的150个点

    然后莫名AC了

    为了再次减少枚举量,本少决定只比较每个点后面的50个点

    然后再次莫名AC了

    为了再次减少枚举量,本少决定只比较每个点后面的3个点

    然后再次莫名AC了

    这是一个玄学问题

    AC代码如下

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <algorithm>
    using namespace std;//流线型头文件
    
    const int Max=200010;
    double x[Max],y[Max];
    
    void Qsort(int l,int r)
    {
        int i,j;
        double a,b;
        i=l;
        j=r;
        a=x[(l+r)/2];
        while(i<=j)
        {
            while(x[i]<a)	i++;
            while(a<x[j])	j--;
            if(i<=j)
            {
                b=x[i];	x[i]=x[j]; x[j]=b;
                b=y[i];	y[i]=y[j]; y[j]=b;
                i++;
                j--;
            }
        }
        if(i<r)	Qsort(i,r);
        if(l<j)	Qsort(l,j);
    }//先给x坐标排序
    
    int main()
    {
        int len;
        scanf("%d",&len);
        for(int i=1; i<=len; i++)
            scanf("%lf%lf",&x[i],&y[i]);
        double mindist=99999999999;
        Qsort(1,len);
        double d;
        for(int i=1; i<=len; i++)
            for(int j=1; j<=3; j++)//比较每个点后面的3个点
                if(i+j<=len)
                {
                    d=sqrt((x[i]-x[i+j])*(x[i]-x[i+j])*1.0+(y[i]-y[i+j])*(y[i]-y[i+j])*1.0);
                    if(d<mindist)	mindist=d;
                }//比较
        printf("%.4lf
    ",mindist);
        return 0;
    }
    
  • 相关阅读:
    渣渣菜鸡的蚂蚁金服面试经历(一)
    20 个案例教你在 Java 8 中如何处理日期和时间?
    Spring Boot 2.0系列文章(七):SpringApplication 深入探索
    分布式锁看这篇就够了
    Spring Boot 2.0系列文章(五):Spring Boot 2.0 项目源码结构预览
    20135337朱荟潼——实验三
    20135337朱荟潼Java实验报告二
    5337朱荟潼Java实验报告一
    Linux内核设计笔记12——内存管理
    Linux内核设计笔记11——定时器
  • 原文地址:https://www.cnblogs.com/vasairg/p/12318449.html
Copyright © 2020-2023  润新知