码迷,mamicode.com
首页 > 其他好文 > 详细

「LuoguP1429」 平面最近点对(加强版)

时间:2018-10-19 22:43:17      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:pac   sdi   getchar   turn   col   1.0   reg   stdout   stdin   

题目描述

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

 

「LuoguP1429」 平面最近点对(加强版)

标签:pac   sdi   getchar   turn   col   1.0   reg   stdout   stdin   

原文地址:https://www.cnblogs.com/qwerta/p/9819241.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!