题意:有n个点,问其中某一对点的距离最小是多少

分析:分治法解决问题:先按照x坐标排序,求解(left, mid)和(mid+1, right)范围的最小值,然后类似区间合并,分离mid左右的点也求最小值

POJ 3714

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> const int N = 1e5 + 5;
const double INF = 1e100;
struct Point {
double x, y;
bool flag;
bool operator < (const Point &rhs) const {
return x < rhs.x;
}
};
Point point[N*2];
int idy[N*2];
int n; bool cmp_y(int i, int j) {
return point[i].y < point[j].y;
} double squ(double x) {
return x * x;
} double get_dist(Point &a, Point &b) {
if (a.flag == b.flag) {
return INF;
}
return sqrt (squ (a.x - b.x) + squ (a.y - b.y));
} double min_dist(int left, int right) {
if (left == right) {
return INF;
}
else if (right - left == 1) {
return get_dist (point[left], point[right]);
} else {
int mid = left + right >> 1;
double ret = std::min (min_dist (left, mid), min_dist (mid + 1, right));
if (ret == 0) {
return ret;
}
int endy = 0;
for (int i=mid; i>=left&&point[mid].x-point[i].x<=ret; --i) {
idy[endy++] = i;
}
for (int i=mid+1; i<=right&&point[i].x-point[mid+1].x<=ret; ++i) {
idy[endy++] = i;
}
std::sort (idy, idy+endy, cmp_y);
for (int i=0; i<endy; ++i) {
for (int j=i+1; j<endy&&point[j].y-point[i].y<ret; ++j) {
ret = std::min (ret, get_dist (point[i], point[j]));
}
}
return ret;
}
} int main() {
int T; scanf ("%d", &T);
while (T--) {
scanf ("%d", &n);
for (int i=0; i<2*n; ++i) {
scanf ("%lf%lf", &point[i].x, &point[i].y);
if (i < n) {
point[i].flag = false;
} else {
point[i].flag = true;
}
}
std::sort (point, point+2*n);
printf ("%.3f\n", min_dist (0, 2 * n - 1));
} return 0;
}

HDOJ 1007

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> const int N = 1e5 + 5;
const double INF = 1e100;
struct Point {
double x, y;
};
Point point[N], py[N];
int n; bool cmp_x(const Point &a, const Point &b) {
return a.x < b.x;
}
bool cmp_y(const Point &a, const Point &b) {
return a.y < b.y;
} double squ(double x) {
return x * x;
} double get_dist(Point &a, Point &b) {
return sqrt (squ (a.x - b.x) + squ (a.y - b.y));
} double min_dist(int left, int right) {
if (left + 1 == right) {
return get_dist (point[left], point[right]);
} else if (left + 2 == right) {
return std::min (get_dist (point[left], point[left+1]),
std::min (get_dist (point[left], point[right]), get_dist (point[left+1], point[right])));
} else {
int mid = left + right >> 1;
double ret = std::min (min_dist (left, mid), min_dist (mid + 1, right));
int cnt = 0;
for (int i=mid; i>=left&&point[mid].x-point[i].x<=ret; --i) {
py[cnt++] = point[i];
}
for (int i=mid+1; i<=right&&point[i].x-point[mid+1].x<=ret; ++i) {
py[cnt++] = point[i];
}
std::sort (py, py+cnt, cmp_y);
for (int i=0; i<cnt; ++i) {
for (int j=i+1; j<cnt&&py[j].y-py[i].y<ret; ++j) {
ret = std::min (ret, get_dist (py[i], py[j]));
}
}
return ret;
}
} int main() {
while (scanf ("%d", &n) == 1) {
if (!n) {
break;
}
for (int i=0; i<n; ++i) {
scanf ("%lf%lf", &point[i].x, &point[i].y);
}
std::sort (point, point+n, cmp_x);
printf ("%.2f\n", min_dist (0, n - 1) / 2);
} return 0;
}

  

最近点对问题 POJ 3714 Raid && HDOJ 1007 Quoit Design的更多相关文章

  1. Hdoj 1007 Quoit Design 题解

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

  2. HDU 1007 Quoit Design(经典最近点对问题)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1007 Quoit Design Time Limit: 10000/5000 MS (Java/Oth ...

  3. (洛谷 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 ...

  4. 杭电OJ——1007 Quoit Design(最近点对问题)

    Quoit Design Problem Description Have you ever played quoit in a playground? Quoit is a game in whic ...

  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【计算几何/分治/最近点对】

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

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

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

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

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

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

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

随机推荐

  1. php安全编程: register_globals的安全性

    register_globals?本身并非安全风险.但是,它为跟踪用户输入和确保应用程序安全增加了难度.为什么会这样? 因为如果打开 register_globals,在全局名称空间和 $_GET.$ ...

  2. ios电话/密码/验证码/身份证的正则表达式

    // 一 .电话号码正则表达式 -(BOOL)testPhoneNumber:(NSString *)text { NSString *regex =@"(13[0-9]|0[1-9]|0[ ...

  3. [Java 基础] 使用java.util.zip包压缩和解压缩文件

    reference :  http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...

  4. September 7th 2016 Week 37th Wednesday

    Patience is bitter, but its fruit is sweet. 忍耐是痛苦的,但它的果实却是甜蜜的. However, many may give up before they ...

  5. Express 4 中如何使用connect-mongo

    正在跟随上面的教程一步一步做,在会话支持那一节中安装 connect-mongo 后,添加: var MongoStore = require('connect-mongo')(express); v ...

  6. sql 查询最近30分钟或者自定义时间数据

    ) FROM dual; 30分钟或者自定义

  7. CROSS JOIN连接用于生成两张表的笛卡尔集

    将两张表的情况全部列举出来 结果表: 列= 原表列数相加 行= 原表行数相乘     CROSS JOIN连接用于生成两张表的笛卡尔集. 在sql中cross join的使用: 1.返回的记录数为两个 ...

  8. 简单的mysql封装类

    class mysql{ private $host; private $user; private $pwd; private $dbname; private $charset; private ...

  9. 【网络资料】Astar算法详解

    关于A*算法,很早就想写点什么,可是貌似天天在忙活着什么,可事实又没有做什么,真是浮躁啊!所以今晚还是来写一下总结吧! A*算法是很经典的只能启发式搜索算法,关于只能搜索算法和一般的搜索算法(例如DF ...

  10. HDU3434 Sequence Adjustment

    题意:给你含有n个数的序列,每次你可以选一个子序列将上面所有的数字加1或者减1,目标是把所有数字变成相同的,问最少步数,和那个相同的数字有多少种可能. 将原序列转化为差分序列,即a[2] - a[1] ...