Quoit Design


Time Limit: 5 Seconds      Memory Limit: 32768 KB

Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring
is carefully designed so it can only encircle one toy at a time. On the other
hand, to make the game look more attractive, the ring is designed to have the
largest radius. Given a configuration of the field, you are supposed to find
the radius of such a ring.

Assume that all the toys are points on a plane. A point is encircled by the
ring if the distance between the point and the center of the ring is strictly
less than the radius of the ring. If two toys are placed at the same point,
the radius of the ring is considered to be 0.

Input

The input consists of several test cases. For each case, the first line contains
an integer N (2 <= N <= 100,000), the total number of toys in the field.
Then N lines follow, each contains a pair of (x, y) which are the coordinates
of a toy. The input is terminated by N = 0.

Output

For each test case, print in one line the radius of the ring required by the
Cyberground manager, accurate up to 2 decimal places.

Sample Input

2
0 0
1 1
2
1 1
1 1
3
-1.5 0
0 0
0 1.5
0

Sample Output

0.71
0.00
0.75

分析:

先将点按照x排序
然后可以可以分为两个区间SL,SR,最近点对的分布情况可以分为3个情况
1.最近点对都在SL
2.最近点对都在SR
3.一个在SR,一个在SL或者相反
1,2种情况都很好解决,直接递归找就可以,假设我们在1,2种情况里面找到了一个最小的距离d,关键就是这第三步,貌似需要n的平方的时间,把左边和右边的两个点都对比一下
其实不用
首先,两边的点,与分割线L的距离超过d的,都可以不看了,其次两个点p1,p2(假设p1左,p2右)与分割线L的距离都小于d,如果他们的纵坐标之差大于d
那么他们也不用看了,这样就是使得可搜索的范围大大减小
然后最重要的来了!!!
对左半部分的,与L的记录在d之内的每个p1来说
右边部分符合上面两个条件的点最多只有6个
原因就是:d是两个半平面各自内,
任意两点的最小距离,因此在同一个半平面内,
任何两点距离都不可能超过d。
我们又要求P1和P2的水平距离不能超过d,
垂直距离也不能超过d,
在这个d*2d的小方块内,最多只能放下6个距离不小于d的点。
因此,第3步总的比较距离的次数不超过n*6。
(嗯~~~也不知道自己说的对不对)
第3步的具体做法是:
3.1删除所有到L的距离大于d的点。 O(n)
3.2把右半平面的点按照纵坐标y排序。 O(nlogn)
3.3对于左半平面内的每个点P1,
找出右半平面内纵坐标与P1的纵坐标的差在d以内的点P2,
计算距离取最小值,算出d3。O(n*6) = O(n)
因为3.2的排序需要O(nlogn),
所以整个算法的复杂度就是O(n((logn)^2))。
整体的思路:
1.把所有的点按照横坐标排序
2.用一条竖直的线L将所有的点分成两等份
3.递归算出左半部分的最近两点距离d1,右半部分的最近两点距离d2,取d=min(d1,d2)
4.算出“一个在左半部分,另一个在右半部分”这样的点对的最短距离d3。
5.结果=min(d1,d2,d3)
 
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define max_v 100005
int n;
struct node
{
double x,y;
}p[max_v];
int a[max_v];
double cmpx(node a,node b)
{
return a.x<b.x;
}
double cmpy(int a,int b)
{
return p[a].y<p[b].y;
}
double dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double slove(int l,int r)
{
if(r==l+)
return dis(p[l],p[r]);
if(l+==r)
return min(dis(p[l],p[r]),min(dis(p[l],p[l+]),dis(p[l+],p[r])));
int mid=(l+r)>>;
double ans=min(slove(l,mid),slove(mid+,r));
int i,j,cnt=;
for(i=l;i<=r;i++)
{
if(p[i].x>=p[mid].x-ans&&p[i].x<=p[mid].x+ans)
{
a[cnt++]=i;
}
}
sort(a,a+cnt,cmpy);
for(i=;i<cnt;i++)
{
for(j=i+;j<cnt;j++)
{
if(p[a[j]].y-p[a[i]].y>=ans)
break;
ans=min(ans,dis(p[a[i]],p[a[j]]));
}
}
return ans;
}
int main()
{
while(~scanf("%d",&n))
{
if(n==)
break;
for(int i=;i<n;i++)
{
scanf("%lf %lf",&p[i].x,&p[i].y);
}
sort(p,p+n,cmpx);
printf("%0.2lf\n",slove(,n-)/2.0);
}
return ;
}
/*
先将点按照x排序
然后可以可以分为两个区间SL,SR
最近点对的分布情况可以分为3个情况
1.最近点对都在SL
2.最近点对都在SR
3.一个在SR,一个在SL或者相反 1,2种情况都很好解决
直接递归找就可以
假设我们在1,2种情况里面找到了一个最小的距离d
关键就是这第三步,貌似需要n的平方的时间,把左边和右边的两个点都对比一下
其实不用
首先,两边的点,与分割线L的距离超过d的,都可以不看了
其次两个点p1,p2(假设p1左,p2右)与分割线L的距离都小于d
如果他们的纵坐标之差大于d
那么他们也不用看了
这样就是使得可搜索的范围大大减小
然后最重要的来了!!!
对左半部分的,与L的记录在d之内的每个p1来说
右边部分符合上面两个条件的点最多只有6个
原因就是:d是两个半平面各自内,
任意两点的最小距离,因此在同一个半平面内,
任何两点距离都不可能超过d。
我们又要求P1和P2的水平距离不能超过d,
垂直距离也不能超过d,
在这个d*2d的小方块内,最多只能放下6个距离不小于d的点。
因此,第3步总的比较距离的次数不超过n*6。
(嗯~~~也不知道自己说的对不对) 第3步的具体做法是:
3.1删除所有到L的距离大于d的点。 O(n)
3.2把右半平面的点按照纵坐标y排序。 O(nlogn)
3.3对于左半平面内的每个点P1,
找出右半平面内纵坐标与P1的纵坐标的差在d以内的点P2,
计算距离取最小值,算出d3。O(n*6) = O(n)
因为3.2的排序需要O(nlogn),
所以整个算法的复杂度就是O(n((logn)^2))。 整体的思路:
1.把所有的点按照横坐标排序
2.用一条竖直的线L将所有的点分成两等份
3.递归算出左半部分的最近两点距离d1,右半部分的最近两点距离d2,取d=min(d1,d2)
4.算出“一个在左半部分,另一个在右半部分”这样的点对的最短距离d3。
5.结果=min(d1,d2,d3) */

ZOJ 2017 Quoit Design 经典分治!!! 最近点对问题的更多相关文章

  1. hdu 1007 Quoit Design (经典分治 求最近点对)

    Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...

  2. HDU1007 Quoit Design 【分治】

    Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  3. poj 1007 Quoit Design(分治)

    Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  4. HDU 1007:Quoit Design(分治求最近点对)

    http://acm.hdu.edu.cn/showproblem.php?pid=1007 题意:平面上有n个点,问最近的两个点之间的距离的一半是多少. 思路:用分治做.把整体分为左右两个部分,那么 ...

  5. HDU 1007 Quoit Design(计算几何の最近点对)

    Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...

  6. (hdu1007)Quoit Design,求最近点对

    Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...

  7. HDU 1007 Quoit Design 平面内最近点对

    http://acm.hdu.edu.cn/showproblem.php?pid=1007 上半年在人人上看到过这个题,当时就知道用分治但是没有仔细想... 今年多校又出了这个...于是学习了一下平 ...

  8. hdu 1007 Quoit Design(平面最近点对)

    题意:求平面最近点对之间的距离 解:首先可以想到枚举的方法,枚举i,枚举j算点i和点j之间的距离,时间复杂度O(n2). 如果采用分治的思想,如果我们知道左半边点对答案d1,和右半边点的答案d2,如何 ...

  9. hdu 1007 Quoit Design(分治)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007 题意:给出n个点求最短的两点间距离除以2. 题解:简单的分治. 其实分治就和二分很像二分的写df ...

随机推荐

  1. ctcms Nginx 伪静态

    location /whole { rewrite ^/whole/(.+).html$ /index.php?c=whole&key=$1; } location /show { rewri ...

  2. 数学建模三剑客MSN

    前言 不管是不是巴萨的球迷,只要你喜欢足球,就一定听说过梅西(Messi).苏亚雷斯(Suarez)和内马尔(Neymar)这个MSN组合.在众多的数学建模辅助工具中,也有一个犀利无比的MSN组合,他 ...

  3. Flutter与Android混合开发及Platform Channel的使用

    相对于单独开发Flutter应用,混合开发对于线上项目更具有实际意义,可以把风险控制到最低,也可以进行实战上线.所以介绍 集成已有项目 混合开发涉及原生Native和Flutter进行通信传输,还有插 ...

  4. Android自定义Button按钮显示样式

    关于listview和button都要改变android原来控件的背景,在网上查找了一些资料不是很全,所以现在总结一下android的selector的用法. 首先android的selector是在 ...

  5. MongoDB学习笔记(一)——Windows 下安装MongoDB

     首先从官网下载mongodb的windows安装包,根据自己系统类型选择32位或者64位版本安装即可,然后根据提示一路下一步即可安装完成.如果没有修改安装目录会默认安装在C:\Program Fil ...

  6. leveldb开篇

    因为工作的需求,最近看了一些项目的源码,包括nginx.tair.leveldb,一直看了下来都没有写东西的习惯,虽然作了不少记录,但都是只有自己才能看懂的笔记. 好多次都说开始写blog,锻炼一下自 ...

  7. Eclipse 控制台视图和服务器视图中停止Web服务器的差别

    Eclipse 控制台视图和服务器视图中停止Web服务器的差别 (1)console视图里面, "红色方形图标" 是terminate, 也会关闭web服务器!!!!!!!!这个, ...

  8. sql server 查询ntext字段长度

    DATALENGTH 返回任何表达式所占用的字节数. 语法 DATALENGTH ( expression ) 参数 expression 任何类型的表达式. 返回类型 int 注释 DATALENG ...

  9. npm run dev时报错“events.js:160 throw er; // Unhandled 'error' event”

    经查,此问题由端口占用导致,node服务器默认端口8080已被其他程序占用,关闭占用端口的程序或者修改node服务器的默认端口即可解决此问题

  10. Python学习---ModelForm拾遗180325

    ModelForm适用于前台验证和后台直接操作数据库的前后台未做分离,可以一次执行验证和保存数据的场景. 注意:  1.  ModelForm里面没有删除方法,需要手动删除内容 2. ModelFor ...