题意是求出所给各点中最近点对的距离的一半(背景忽略)。

用分治的思想,先根据各点的横坐标进行排序,以中间的点为界,分别求出左边点集的最小距离和右边点集的最小距离,然后开始合并,分别求左右点集中各点与中间点的距离,从这些距离与点集中的最小距离比较,求得最小距离,此处可按纵坐标排序,将纵坐标距离已经大于之前最小距离的部分都剪枝。

代码如下:

 #include <bits/stdc++.h>
using namespace std;
int n,a[];
struct point
{
double x,y;
}p[];
bool cmpx(point a,point b)
{
return a.x < b.x;
}
bool cmpy(int a,int b)
{
return p[a].y < p[b].y;
}
double dis(point a,point b)
{
return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
}
double min(double a,double b,double c)
{
if(a>b) return b>c?c:b;
return a>c?c:a;
}
double fin(int from,int to)
{
if(from+ == to ) return dis(p[from],p[to]);
if(from+ == to ) return min(dis(p[from],p[from+]),dis(p[from],p[to]),dis(p[from+],p[to]));
int mid = (from+to)>>;
double ans = min(fin(from,mid),fin(mid+,to));
int cnt = ;
for(int i = from; i <= to; i++)
if(abs(p[i].x-p[mid].x) <= ans) a[cnt++] = i;
sort(a,a+cnt,cmpy);
for(int i = ; i < cnt; i++)
for(int 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)&&n)
{
for(int i = ; i < n; i++)
scanf("%lf %lf",&p[i].x,&p[i].y);
sort(p,p+n,cmpx);
printf("%.2lf\n",fin(,n-)/);
}
return ;
}

但是呢,开始时本人并不是这么写的,而是求了所有点中最小的横坐标和纵坐标,然后以此为参照点,分别求其他各点到参照点的距离,以距离排序,再求出相邻两点距离的最小值。这么写是上面写法的用时一半左右,尽管 AC 了,但是这么写是不对的......

如图所示,图中的点 1 和点 2 距离比点 1 和点 3 的距离更近,但是第二种方法则是用点 1 和点 3距离与点 3 和点 2 距离中求较小值。(题目的测试数据中可能没有这样的数据吧......)

第二种方法的代码如下:

 #include <bits/stdc++.h>
using namespace std;
int n;
struct point
{
double x,y,dis;
}st,p[];
bool cmp(point a,point b)
{
if(a.dis!=b.dis) return a.dis < b.dis;
return a.x<b.x;
}
double dist(point a,point b)
{
return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
}
int main()
{
double sml;
while(scanf("%d",&n)&&n)
{
st.x = st.y = 1000000.0;
sml = 1000000.0;
for(int i = ; i < n; i++)
{
scanf("%lf %lf",&p[i].x,&p[i].y);
if(p[i].x < st.x) st.x = p[i].x;
if(p[i].y < st.y) st.y = p[i].y;
}
for(int i = ; i < n; i++)
p[i].dis = dist(p[i],st);
sort(p,p+n,cmp);
for(int i = ; i < n; i++)
if(dist(p[i],p[i-])<sml) sml = dist(p[i],p[i-]);
printf("%.2lf\n",sml/);
}
return ;
}

HDU 1007(套圈 最近点对距离)的更多相关文章

  1. hdu 1007 Quoit Design (最近点对问题)

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

  2. HDU 1007 Quoit Design最近点对( 分治法)

    题意: 给出平面上的n个点,问任意点对之间的最短距离是多少? 思路: 先将所有点按照x坐标排序,用二分法将n个点一分为二个部分,递归下去直到剩下两或一个点.对于一个部分,左右部分的答案分别都知道,那么 ...

  3. Quoit Design (HDU 1007)平面的最近点对

    题目大意:给定平面上的 n 个点,求距离最近的两个点的距离的一半. n <= 10^5.   晕乎乎的度过了一上午... 总之来学习下分治吧233 分治就是把大问题拆成小问题,然后根据对小问题处 ...

  4. HDU 1007 平面上最近点对 分治

    思路: 分治 套路题 //By SiriusRen #include <cmath> #include <cstdio> #include <algorithm> ...

  5. hdu 1007 Quoit Design 分治求最近点对

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

  6. HDU 1007 Quoit Design

    传送门 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Des ...

  7. 【HDU 1007】 Quoit Design

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1007 [算法] 答案为平面最近点对距离除以2 [代码] #include <algorith ...

  8. HDU 1007 Quoit Design(二分+浮点数精度控制)

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

  9. UVA10054-The Necklace(无向图欧拉回路——套圈算法)

    Problem UVA10054-The Necklace Time Limit: 3000 mSec Problem Description Input The input contains T t ...

随机推荐

  1. 华为Python 算法面试题

    华为算法面试题 """ 算法题: 提供一个序列,完成对这个序列的分割.要求分割后的两个序列彼此差值最小 实现函数,返回两个序列 """ de ...

  2. ARC 086 E - Smuggling Marbles(dp + 启发式合并)

    题意 Sunke 有一棵 \(N + 1\) 个点的树,其中 \(0\) 为根,每个点上有 \(0\) 或 \(1\) 个石子, Sunke 会不停的进行如下操作直至整棵树没有石子 : 把 \(0\) ...

  3. 【php】 php获取文件路径中的文件名和文件后缀方法

    获取文件名 $file = realpath(__DIR__.'/images/common/../addBtn.png'); 方法一 $file = realpath(__DIR__.'/image ...

  4. 【linux】vim常用操作及vim插件的安装使用

    vim是linux下一个非常好用的文本编辑器,在linux下开发的人员要熟练掌握vim常用命令. 1.  打开在第n行 vim +143 filename.txt 2. 只读模式打开 vim -R / ...

  5. Jira配置openLdap服务器进行用户认证

    测试环境 注:进过测试,Jira6.3.6和Jira7.3.8界面和配置方法相同,不过7.3.x版本默认的用户组只有jira-software-users和jira-administrators,好在 ...

  6. php 写斐波那契数列

    <?php $arr = []; for($i=1;$i<9;$i++){ if($i==1 || $i ==2){ $arr[$i-1] = 1; }else{ $arr[$i-1] = ...

  7. poj1182、hdu1829(并查集)

    题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: ...

  8. vue--传值

    传值:(如果传的是引用类型,当值发生改变时所有绑定他的全都发生改变,如果传的时值类型,就只有他自己发生改变) 父传子: 父页面:父组件定义一个属性 users:[ {name:'张三',positio ...

  9. bzoj2208 连通数(bitset优化传递闭包)

    题目链接 思路 floyd求一下传递闭包,然后统计每个点可以到达的点数. 会tle,用bitset优化一下.将floyd的最后一层枚举变成bitset. 代码 /* * @Author: wxyww ...

  10. 数据库MySQL

    --IN 关键字 在.....里 SELECT * FROM zhangwu WHERE money IN (66,666,700); 1.主键约束 特点非空 只用于表示當前的记录 primary k ...