洛谷P1429 平面最近点对(加强版)
来源:互联网 发布:淘宝手机怎样投诉卖家 编辑:程序博客网 时间:2024/06/18 10:56
题目描述
给定平面上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
题解
这是一道分治。
首先,暴力枚举点对计算是n^2,肯定超。
然后数据范围200000,就肯定是nlogn的算法,然后我就想到二分答案,也进行了实现,然后,就没有然后了。。。
于是我就愉快地看了题解,发现确实是二分,可是只是二分区间,然后再合并,就像归并排序。
忽然发现很有道理,因为,点对是两个点,然后就可以分治地去找到满足条件的点对,并更新答案了。
然后,我就写了一遍,还是很好写的,真的很像归并排序求逆序对。
然后我就交了一次:
结果60,我就当场懵逼。。
然后回去看题解,发现他写了实数读入优化,我就copy过来,想着试一试,又交了一次,然后:
wtf,这都行???
还有,为什么还是有一个WA?
于是我就开始看我和他的程序有什么区别,发现排序的函数,他多判了一种x相等时比较y,我就加上了,然后重新交了一次:
还有这种操作???
这么差下来,就是60-100的差距呀,这一般都是算法差距呀。。。。。。。
我只能说,这题太阴险了。。
你们自己可以去体会体会。
至于这题算法具体描述,我懒得自己写了,copy一段(来自@xzyxzy):
于是——怎么分
✔将各个点(结构体)按x的从小到大排序
✔首先运用二分思想将点集合分到最后只剩两个点的时候
✔然后用这两点之间的距离更新答案(答案初始化为无限大)
✔然后我们要找到二分的具体实现方案——每次分到一些点时,找到这些点标号的中间(因为点都排好序了,所以其实也就是找到x轴上一条分界线),将整个点的集合大致均分为两个部分
✔在分界线的右侧,将与分界线的距离小于ans的点纳入到一个辅助结构体里面
✔在分界线的左侧,不断枚举点,枚举到离分界线小于ans的点时,与辅助结构体中的点挨个(等会有解释)判断其距离有没有小于ans,更新ans
注意下用double别掉了精度,然后格式化输出就好了
然后我的代码中,为了避免超时,还是很努力地自己写了个实数的输入优化没想到也过了
最后,贴一下代码:
#include<bits/stdc++.h>#define ll long long#define inf 0x3f3f3f3fusing namespace std;const double eps=0.0001;double read(){ char ch=getchar(); while(ch!='.'&&(ch>'9'||ch<'0')) ch=getchar(); int h=0,t=1,b=0; while(ch!='.'&&ch<='9'&&ch>='0') { h=h*10+ch-48; ch=getchar(); } if(ch=='.') { ch=getchar(); while(ch<='9'&&ch>='0') { b=b*10+ch-48; ch=getchar(); t*=10; } } return h+(b*1.000000000)/t;}struct point{ double x,y; bool operator < (const point& b) const { return x==b.x?y<b.y:x<b.x; }}p[200001],g[200001];int n;inline double getdis(const point& a,const point& b){ double cx=b.x-a.x; double cy=b.y-a.y; return sqrt(cx*cx+cy*cy);}double ans=inf;void func(int l,int r){ if(l==r){ return; } int mid=(l+r)/2; func(l,mid); func(mid+1,r); double line=p[mid].x; int t=1; int cnt=0; for(int i=mid+1;i<=r;i++){ if(p[i].x-line<ans){ g[++cnt]=p[i]; } } for(int i=l;i<=mid;i++){ if(line-p[i].x>=ans)continue; while(t<=cnt&&fabs(g[t].y-p[i].y)<ans){ ans=min(ans,getdis(p[i],g[t])); t++; } }}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ p[i].x=read(); p[i].y=read(); } sort(p+1,p+n+1); func(1,n); printf("%.4lf",ans); return 0;}
end
- 洛谷P1429 平面最近点对(加强版)
- luogu 1429 平面最近点对(加强版)
- 分治——Luogu1429 平面最近点对(加强版)
- 平面最近点对
- 平面最近点对
- 平面最近点对
- 平面最近点对
- 平面最近点对
- 平面最近点对
- 平面最近点对
- 平面最近点对
- 平面最近点对
- 平面最近点对 转载
- hdu1007 平面最近点对
- POJ_3714_Raid(平面最近点对)
- 平面最近距离点对
- 平面上最近点对
- 平面最近点对问题
- 红黑树详解
- MySQL数据库备份还原(基于binlog的增量备份)
- 安卓工作室 android studio 的 汉化 美化 定制 Android studio's Chinesization beautification customization
- 单选按钮和复选框
- Unity3D数学基础(4)_ 简单的排序算法总结
- 洛谷P1429 平面最近点对(加强版)
- Android中的Selector的用法
- 下拉列表框
- 一看就懂系列之 由浅入深聊一聊php的垃圾回收机制
- 普通按钮+提交按钮+重置按钮
- dtcms5源码下载 dtcms5.0.1 最新ASP.NET源码 MSSQL版本源码今日公开发布
- 关于在ubuntu服务器上安装R的igraphe的包遇到的问题的解决方案
- BP神经网络样本数多少有什么影响 ?
- 【Leetcode】【python】Longest Palindromic Substring