版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/。未经本作者同意不得转载。

https://blog.csdn.net/kenden23/article/details/36407517

本题是一般近期对点求解。略微添加点限定:有两个集合点,要求不同集合中的点的近期对。

那么就添加一个推断。假设是同一个集合中的点,那么就返回最大值。其它和一般的近期对点解法一样。

注意:本题数据有重合点。那么就要防止分类的时候溢出。

Geeks上的近期对的程序是无法处理有重合点的情况的。


#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <algorithm>
#include <string.h>
using std::sort;
struct Point
{
int x, y;
int whichSet;
}; inline int xCmp(const void *a, const void *b)
{
const Point *a1 = static_cast<const Point *>(a);
const Point *b1 = static_cast<const Point *>(b);
return a1->x - b1->x;
} inline int xCmp2(const Point &a, const Point &b)
{
return a.x < b.x;
} inline int yCmp2(const Point &a, const Point &b)
{
return a.y < b.y;
} inline int yCmp(const void *a, const void *b)
{
const Point *a1 = static_cast<const Point *> (a);
const Point *b1 = static_cast<const Point *> (b);
return a1->y - b1->y;
} inline float dist(Point &a, Point &b)
{
if (a.whichSet == b.whichSet) return FLT_MAX;
float xd = (float)(a.x - b.x);
float yd = (float)(a.y - b.y);
return sqrtf(xd*xd + yd*yd);
} float bruteForce(Point P[], int n)
{
float m = FLT_MAX;
for (int i = 0; i < n; ++i)
{
for (int j = i+1; j < n; ++j)
{
float d = dist(P[i], P[j]);
if (d < m) m = d;
}
}
return m;
} inline float mMin(float x, float y) { return x < y? x : y; } float stripClosest(Point strip[], int n, float d)
{
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n && strip[j].y -strip[i].y < d; j++)
{
float t = dist(strip[i], strip[j]);
if (t < d) d = t;
}
}
return d;
} float closestUtil(Point Px[], Point Py[], int n)
{
if (n <= 3) return bruteForce(Px, n); int m = n >> 1;
Point midPoint = Px[m]; Point *PyL = new Point[m+1];
Point *PyR = new Point[n-m-1];
int le = 0, ri = 0;
for (int i = 0; i < n; i++)
{//修正bug:添加le<m+1推断。防止反复点。引起溢出
if (Py[i].x <= midPoint.x && le < m+1) PyL[le++] = Py[i];
else PyR[ri++] = Py[i];
} float dl = closestUtil(Px, PyL, le);//m+1);
float dr = closestUtil(Px+m+1, PyR, ri);//n-m-1); float d = mMin(dl, dr); Point *strip = new Point[n];
int j = 0;
for (int i = 0; i < n; i++)
{
if (fabsf(float(Py[i].x - midPoint.x)) < d) strip[j++] = Py[i];
}
d = mMin(d, stripClosest(strip, j, d));
delete [] strip;
delete [] PyL;
delete [] PyR;
return d;
} float closest(Point P[], int n)
{
Point *Px = new Point[n];
Point *Py = new Point[n];
memcpy(Px, P, n * sizeof(Point));
memcpy(Py, P, n * sizeof(Point)); //qsort(Px, n, sizeof(Point), xCmp);
sort(Px, Px+n, xCmp2);
//qsort(Py, n, sizeof(Point), yCmp);
sort(Py, Py+n, yCmp2); float d = closestUtil(Px, Py, n);
delete [] Px;
delete [] Py;
return d;
} int main()
{
int T, n;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
Point *P = new Point[n<<1];
for (int i = 0; i < n; i++)
{
scanf("%d %d", &P[i].x, &P[i].y);
P[i].whichSet = 1;
}
for (int i = n; i < (n<<1); i++)
{
scanf("%d %d", &P[i].x, &P[i].y);
P[i].whichSet = 2;
}
printf("%.3f\n", closest(P, n<<1));
delete [] P;
}
return 0;
}

POJ 3714 Raid 近期对点题解的更多相关文章

  1. 最近点对问题 POJ 3714 Raid && HDOJ 1007 Quoit Design

    题意:有n个点,问其中某一对点的距离最小是多少 分析:分治法解决问题:先按照x坐标排序,求解(left, mid)和(mid+1, right)范围的最小值,然后类似区间合并,分离mid左右的点也求最 ...

  2. POJ 3714 Raid(平面近期点对)

    解题思路: 分治法求平面近期点对.点分成两部分,加个标记就好了. #include <iostream> #include <cstring> #include <cst ...

  3. poj 3714 Raid【(暴力+剪枝) || (分治法+剪枝)】

    题目:  http://poj.org/problem?id=3714 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27048#prob ...

  4. POJ 3714 Raid

    Description After successive failures in the battles against the Union, the Empire retreated to its ...

  5. poj 3714 Raid(平面最近点对)

    Raid Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7473   Accepted: 2221 Description ...

  6. POJ 3714 Raid(计算几何の最近点对)

    Description After successive failures in the battles against the Union, the Empire retreated to its ...

  7. (洛谷 P1429 平面最近点对(加强版) || 洛谷 P1257 || Quoit Design HDU - 1007 ) && Raid POJ - 3714

    这个讲的好: https://phoenixzhao.github.io/%E6%B1%82%E6%9C%80%E8%BF%91%E5%AF%B9%E7%9A%84%E4%B8%89%E7%A7%8D ...

  8. 【POJ 3714】Raid

    [题目链接]:http://poj.org/problem?id=3714 [题意] 给你两类的点; 各n个; 然后让你求出2*n个点中的最近点对的距离; 这里的距离定义为不同类型的点之间的距离; [ ...

  9. 【POJ 3714】 Raid

    [题目链接] http://poj.org/problem?id=3714 [算法] 分治求平面最近点对 [代码] #include <algorithm> #include <bi ...

随机推荐

  1. - > 动规讲解基础讲解六——编辑距离问题

    给定两个字符串S和T,对于T我们允许三种操作: (1) 在任意位置添加任意字符(2) 删除存在的任意字符(3) 修改任意字符 问最少操作多少次可以把字符串T变成S?  例如: S=  “ABCF”   ...

  2. ios编程规范

    允许使用较长的描述尽量不要使用缩写,而是将完整的意思写出来.源于代码的维护可能会被不同文化背景的programmer阅读 适当的命名前缀,比如给变量,协议等,不要给方法加前缀 方法命名规则一般以小写字 ...

  3. sublime text常用快捷键(转)

    选择一个选中项的下一个匹配项: ctrl+d 把光标放在一个单词上,按下ctrl+ D,将选择这个单词.一直按住ctrl且按D多次,将选择当前选中项的下一个匹配项.通过按住ctrl,再按D三次,将选择 ...

  4. ElasticSearch和Hive做整合

    1.上传elasticsearh-hadoop的jar包到server1-hadoop-namenode-01上 在server1-hadoop-namenode-01上执行: cp  /home/d ...

  5. 转: maven打可执行的jar包以及classpath设置

    from:  http://drizzlewalk.blog.51cto.com/2203401/416508

  6. UISegmentedControl的具体使用

    当用户输入不不过布尔值时.可使用分段控件(UISegmentedControl).分段控件提供一栏button(有时称为button栏),但只能激活当中一个button. 分段控件会导致用户在屏幕上看 ...

  7. webstrom 应用 转(http://blog.csdn.net/zghekuiwu/article/details/54382145)

    WebStorm 是 JetBrains 推出的一款商业的 JavaScript 开发工具 任何一个编辑器都需要保存(ctrl + s),这是所有win平台上编辑类软件的特点,但是webstorm编辑 ...

  8. Windows Thin PC体验 & 语言包更改(win 7 included)

    本作品由Man_华创作,采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可.基于http://www.cnblogs.com/manhua/上的作品创作. 简介: Window ...

  9. Oracle 中session和processes的初始设置

    http://blog.163.com/succu/blog/static/193917174201252911727149/ 1.sessions   在初始化参数所设定的限制中,最为人所知的估计就 ...

  10. python中executemany的使用

    conn = MySQLdb.connect(host = “localhost”, user = “root”, passwd = “password”, db = “myDB”, charset= ...