最近点对问题 POJ 3714 Raid && HDOJ 1007 Quoit Design
题意:有n个点,问其中某一对点的距离最小是多少
分析:分治法解决问题:先按照x坐标排序,求解(left, mid)和(mid+1, right)范围的最小值,然后类似区间合并,分离mid左右的点也求最小值
#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;
}
#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的更多相关文章
- Hdoj 1007 Quoit Design 题解
Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...
- HDU 1007 Quoit Design(经典最近点对问题)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1007 Quoit Design Time Limit: 10000/5000 MS (Java/Oth ...
- (洛谷 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 ...
- 杭电OJ——1007 Quoit Design(最近点对问题)
Quoit Design Problem Description Have you ever played quoit in a playground? Quoit is a game in whic ...
- hdu 1007 Quoit Design (最近点对问题)
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- HDU 1007 Quoit Design【计算几何/分治/最近点对】
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- hdu 1007 Quoit Design 分治求最近点对
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- poj 3714 Raid(平面最近点对)
Raid Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7473 Accepted: 2221 Description ...
- POJ 3714 Raid(计算几何の最近点对)
Description After successive failures in the battles against the Union, the Empire retreated to its ...
随机推荐
- IOS- 自定义 UIButton
#pragma mark init方法内部默认会调用initWithFrame: - (id)initWithFrame:(CGRect)frame { self = [super initWithF ...
- 2048控制台程序:一份帝国理工C++作业
#include <fstream> #include <vector> #include <iostream> #include <string> u ...
- September 23rd 2016 Week 39th Friday
Even a small star shines in the darkness. 星星再小,也会发光. In the darkness, even a small star can shine. N ...
- MD(markdown)语法
#标题1 ##标题2 段落->空行分隔 `加背景` [超链接](https://www.baidu.com) **加粗** _斜体_ ~~删除线~~ . 列表一 . 列表二 图片: ![alt ...
- 手工加载DLL
1.为了能找到dll的函数地址,生成dll时需要将其中的函数声明为C函数(extern "C"): #ifndef __MYDLL_H#define __MYDLL_H #ifde ...
- 384. Shuffle an Array
Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...
- Android Tab -- 使用ViewPager、PagerAdapter来实现
原文地址:http://blog.csdn.net/crazy1235/article/details/42678877 效果:滑动切换,自动切换. 代码:https://github.com/ldb ...
- 数据结构和算法 – 9.二叉树和二叉查找树
9.1.树的定义 9.2.二叉树 人们把每个节点最多拥有不超过两个子节点的树定义为二叉树.由于限制子节点的数量为 2,人们可以为插入数据.删除数据.以及在二叉树中查找数据编写有效的程序了. 在 ...
- 无废话Android之listview入门,自定义的数据适配器、采用layoutInflater打气筒创建一个view对象、常用数据适配器ArrayAdapter、SimpleAdapter、使用ContentProvider(内容提供者)共享数据、短信的备份、插入一条记录到系统短信应用(3)
1.listview入门,自定义的数据适配器 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and ...
- ASP.NET Web API 配置返回的json字段的格式以及Action返回HttpResponseMessage类型和IHttpActionResult类型
1. 对于返回的Json对象格式是以“帕斯卡”风格的(例如“FirstName”),然而我们的Api有很大的可能被带有Javascript的客户端消费,对于JS开发者来说可能更适合“驼峰”风格(例如” ...