LG1429 平面最近点对(加强版)
题意
给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的
2≤n≤200000
分析
参照3A17K的题解。
我们充分发扬人类智慧:
将所有点全部绕原点旋转同一个角度,然后按xx坐标排序
根据数学直觉,在随机旋转后,答案中的两个点在数组中肯定不会离得太远
所以我们只取每个点向后的5个点来计算答案
这样速度快得飞起,在n=1000000时都可以在1s内卡过
……
代码
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+50;
#define D double
struct spot{
D a[4];
}p[N];
D x,y,x_,y_,z,w,ans;
int n;
bool mmp(const spot &u,const spot &v){
return u.a[0]<v.a[0];
}
int main(){
scanf("%d",&n);
z=sin(1),w=cos(1); //旋转1弧度≈57°
for(int i=1;i<=n;i++){
scanf("%lf%lf",&x,&y);
x_=x*w-y*z;
y_=x*z+y*w; //计算旋转后的坐标
p[i].a[0]=x_;
p[i].a[1]=y_;
p[i].a[2]=x;
p[i].a[3]=y; //存下来
}
sort(p+1,p+n+1,mmp); //排序
for(int i=n+1;i<=n+10;i++)
p[i].a[0]=p[i].a[1]=-N-0.01; //边界处理
ans=2e9+0.01; //初始化答案
for(int i=1;i<=n;i++)
for(int j=1;j<=5;j++){ //枚举
x=p[i].a[2];y=p[i].a[3];
x_=p[i+j].a[2];y_=p[i+j].a[3];
z=sqrt((x-x_)*(x-x_)+(y-y_)*(y-y_)); //计算距离
if(ans>z)ans=z; //更新答案
}
printf("%.4lf\n",ans); //输出
}
/*
x'=xcosθ-ysinθ
y'=xsinθ+ycosθ
*/
正常向的代码
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long ll;
using namespace std;
co double INF=1e18;
co int N=2e5+1;
struct node{
double x,y;
}a[N],b[N];
bool cx(co node&a,co node&b){
return a.x<b.x;
}
bool cy(co node&a,co node&b){
return a.y<b.y;
}
double dis(co node&a,co node&b){
return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}
double merge(int l,int r){
if(l==r) return INF;
int mid=(l+r)>>1,cnt=0;
double ans=min(merge(l,mid),merge(mid+1,r));
for(int i=l;i<=r;++i) if(abs(a[i].x-a[mid].x)<=ans)
b[++cnt]=a[i];
sort(b+1,b+cnt+1,cy);
for(int i=1;i<=cnt;++i)
for(int j=i+1;j<=cnt;++j){
if(b[j].y-b[i].y>ans) break;
ans=min(ans,dis(b[i],b[j]));
}
return ans;
}
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n=read<int>();
for(int i=1;i<=n;++i)
read(a[i].x),read(a[i].y);
sort(a+1,a+n+1,cx);
printf("%.4lf",merge(1,n));
return 0;
}
LG1429 平面最近点对(加强版)的更多相关文章
- P1429 平面最近点对[加强版] 随机化
LINK:平面最近点对 加强版 有一种分治的做法 因为按照x排序分治再按y排序 可以证明每次一个只会和周边的六个点进行更新. 好像不算很难 这里给出一种随机化的做法. 前置知识是旋转坐标系 即以某个点 ...
- 「LuoguP1429」 平面最近点对(加强版)
题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的 输入输出格式 输入格式: 第一行:n:2≤n≤200000 接下来n行:每行两个实数:x y, ...
- Luogu P1429 平面最近点对(加强版)(分治)
P1429 平面最近点对(加强版) 题意 题目描述 给定平面上\(n\)个点,找出其中的一对点的距离,使得在这\(n\)个点的所有点对中,该距离为所有点对中最小的. 输入输出格式 输入格式: 第一行: ...
- P1429 平面最近点对(加强版)(分治)
P1429 平面最近点对(加强版) 主要思路: 分治,将点按横坐标为第1关键字升序排列,纵坐标为第2关键字升序排列,进入左半边和右半边进行分治. 设d为左右半边的最小点对值.然后以mid这个点为中心, ...
- [Luogu1429]平面最近点对(加强版)
题目大意: 平面最近点对. 思路: 分治. 首先将所有点排序 每次把当前区间分为两半,递归求解两个区间内部的情况,然后枚举区间两边的点. #include<cmath> #include& ...
- 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点
平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...
- HDU-4631 Sad Love Story 平面最近点对
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4631 数据是随机的,没有极端数据,所以可以分段考虑,最小值是一个单调不增的函数,然后每次分治算平面最近 ...
- HDU1007--Quoit Design(平面最近点对)
Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...
- Vijos 1012 清帝之惑之雍正 平面最近点对(分治)
背景 雍正帝胤祯,生于康熙十七年(1678)是康熙的第四子.康熙61年,45岁的胤祯继承帝位,在位13年,死于圆明园.庙号世宗. 胤祯是在康乾盛世前期--康熙末年社会出现停滞的形式下登上历史舞台的.复 ...
随机推荐
- ajax实现用户注册
需求分析 页面中给出注册表单: 在username input标签中绑定onblur事件处理函数. 当input标签失去焦点后获取 username表单字段的值,向服务端发送AJAX请求: djang ...
- XAMPP apache443端口被占用
点击netstat,可以看到443端口被vmvare占用,那只能改端口了, config,选择Apache(http-ssl.conf)文件,找到443端口,改成其他不被占用的端口,就可以了.
- angular directive restrict 的用法
E 表示该指令是一个element; A 表示该指令是attribute; C 表示该指令是class; M 表示该指令是注视 实例如下: 原帖:www.thinkster.io/angularjs/ ...
- UVA-11294 Wedding (2-SAT)
题目大意:一张长桌,n对夫妻,编号为0~n,这些人要坐在长桌两侧,每对夫妻不能坐在同一侧.其中,有2*m个人相互讨厌,编号为0的夫妻中的妻子不愿意让对面那一侧中有两个相互吵过架的人,找一种排座位方案. ...
- 你真的会使用Chrome开发者工具吗?
Chrome开发工具是一个Web开发者的利器,使用它你可以实现: 管理界面元素 断点调试JavaScript代码 优化你的代码 这里将列出一些非常实用的使用技巧,帮助你更加高效的工作 1. 快速编辑H ...
- 【Windows】Python脚本随机启动
Python脚本的管理在linux系统上市非常方便的,在windows则不是很方面.但是由于之前对于Windows这块的内容不是很了解,其实计划任务也是不错的,但和linux相比起来还是欠缺了那么点. ...
- 网页重构中区分IE6、IE7、IE8及标准浏览器的最佳方法
由于万恶的IE6和IE7,我们在页面重构时不免要对其进行各种bug修复及差异化处理.在标准浏览器中可实现的效果在IE里却有各种离奇问题,例如IE6.IE7不能良好应对的inline-block和.cl ...
- 普通用户开通sudo权限:xxx is not in the sudoers file.This incident will be reported.的解决方法
1.切换到root用户下,怎么切换就不用说了吧,不会的自己百度去. 2.添加sudo文件的写权限,命令是: chmod u+w /etc/sudoers 3.编辑sudoers文件 vi /etc/s ...
- hdu 6040 Hints of sd0061(stl: nth_element(arr,arr+k,arr+n))
Hints of sd0061 Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- ZOJ 2965 Accurately Say "CocaCola"!(预处理)
Accurately Say "CocaCola"! Time Limit: 2 Seconds Memory Limit: 65536 KB In a party he ...