zoukankan      html  css  js  c++  java
  • 「LuoguP1429」 平面最近点对(加强版)

    题目描述

    给定平面上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

    题解

    考场清晰的记得以前听过,并且记错做法还觉得自己是天才......

    考场思路:按横轴排序,然后从左往右枚举每个点,把和该点的横坐标之差小于$ans$的点暴力算。

    然后怕构造数据被卡(很多个点的横坐标差不多,竖轴差很多的话可以卡成$N$方),于是考虑用权值线段树优化竖轴,也就是从权值线段树中取竖轴在当前点加减ans范围的点暴力算。(考试$x,y$范围1e6)

    这样应该就不会T了......

    然后毒瘤评测人只给64M啊!哪里够开权值线段树啊!

    于是把扫描线转了45°(也可以理解为把纸转45°),再做类暴力,这样就不好卡了。

    然后就过了2333

     1 /*
     2     qwerta
     3     P1429 平面最近点对(加强版)
     4     Accepted
     5     100
     6     代码 C++,1.16KB
     7     提交时间 2018-10-19 15:55:35
     8     耗时/内存
     9     348ms, 2064KB
    10 */
    11 #include<algorithm>
    12 #include<iostream>
    13 #include<cstdio>
    14 #include<cmath>
    15 using namespace std;
    16 #define R register
    17 inline int read()
    18 {
    19     char ch=getchar();
    20     int x=0;
    21     while(!isdigit(ch))ch=getchar();
    22     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    23     return x;
    24 }
    25 const int MAXN=200000+3,MAXX=1000000+3;
    26 struct emm{
    27     int x,y;
    28 }a[MAXN];
    29 const double k=-0.5;
    30 bool cmp(emm qaq,emm qwq)
    31 {
    32     return qaq.y-k*qaq.x<qwq.y-k*qwq.x;
    33 }
    34 inline double dis(int u,int v)
    35 {
    36     return sqrt(1LL*(a[u].x-a[v].x)*(a[u].x-a[v].x)+1LL*(a[u].y-a[v].y)*(a[u].y-a[v].y));
    37 }
    38 double gen2=sqrt(2);
    39 inline double je(int u,int v)
    40 {
    41     return abs(((a[u].y-k*a[u].x)-(a[v].y-k*a[v].x)))/gen2;
    42 }
    43 int main()
    44 {
    45     //freopen("dark.in","r",stdin);
    46     //freopen("dark.out","w",stdout);
    47     int n=read();
    48     for(R int i=1;i<=n;++i)
    49       a[i].x=read(),a[i].y=read();
    50     sort(a+1,a+n+1,cmp);
    51     int l=1,r=1;
    52     double ans=dis(1,2);
    53     for(R int u=1;u<=n;++u)
    54     {
    55         while(je(u,l)>ans)++l;
    56         while(je(r+1,u)<ans&&r<n)++r;
    57         //cout<<u<<" "<<l<<" "<<r<<endl;
    58         for(R int v=l;v<=r;++v)
    59         if(u!=v)
    60         ans=min(ans,dis(u,v));
    61     }
    62     printf("%.4f",ans);
    63     return 0;
    64 }
  • 相关阅读:
    测试面试题集锦(一)| 软件测试常见必考问题与流程篇(附答案)
    测试开发赏金内推 | BAT 最新高薪急聘岗位,名企测试负责人等你来面!
    Xbox分辨率突然变成640p
    UWP 自定义密码框控件
    前端笔记(Antd将组件设置国际化中文)
    【数据结构与算法】背包问题总结梳理
    Redis网络模型的源码分析
    [MOOC-Java]1.2.1用变量做计算
    [MOOC-Java]1.1.2第一个程序
    [MOOC-Java]1.1.1开发环境配置
  • 原文地址:https://www.cnblogs.com/qwerta/p/9819241.html
Copyright © 2011-2022 走看看