HDU1007 Quoit Design

来源:互联网 发布:货到付款淘宝网商城 编辑:程序博客网 时间:2024/05/01 02:26

题目链接

题意不用多说,求平面最近点对的,很简单……我又是一大堆的板子往上面一放,代码就比较长

最近点对,就是分治的方法来求,一半一半地分下去,同时找到x最近的一些点,然后合并的时候枚举比刚刚求到的距离范围内的点,然后求y,整个复杂度应该湿nlogn级别的……还是该理解理解然后脱离板子。

#include <cstdio>#include <cstring>#include <algorithm>#include <cstdlib>#include <cmath>using namespace std;const int maxn = (int)1e5 + 10;const double eps = 1e-8;int cmp(double x){if (fabs(x) < eps) return 0;if (x > 0) return 1;return -1;}inline double sqr(double x){return x * x;}struct point{double x, y;point(){}point(double a, double b) : x(a), y(b){}void input(){scanf("%lf%lf", &x, &y);}friend point operator + (const point &a, const point &b){return point(a.x + b.x, a.y + b.y);}friend point operator - (const point &a, const point &b){return point(a.x - b.x, a.y - b.y);}friend bool operator == (const point &a, const point &b){return cmp(a.x - b.x) == 0 && cmp(a.y - b.y) == 0;}friend point operator * (const double &a, const point &b){return point(a * b.x, a * b.y);}friend point operator / (const point &a, const double &b){return point(a.x / b, a.y / b);}double norm(){return sqrt(sqr(x) + sqr(y));}};double det(const point &a, const point &b){return a.x * b.y - a.y * b.x;}double dot(const point &a, const point &b){return a.x * b.x + a.y * b.y;}double dist(const point &a, const point &b){return (a - b).norm();}point rotate_point(const point &p, double A){double tx = p.x, ty = p.y;return point(tx * cos(A) - ty * sin(A), tx * sin(A) + ty * cos(A));}point a[maxn];int n, s[maxn];bool cmpx(int i, int j){return cmp(a[i].x - a[j].x) < 0;}bool cmpy(int i, int j){return cmp(a[i].y - a[j].y) < 0;}double min_dist(point a[], int s[], int l, int r){double ans = 1e100;if (r - l < 20){for (int q = l; q < r; q++)for (int w = q + 1; w < r; w++)ans = min(ans, (a[s[q]] - a[s[w]]).norm());return ans;}int tl, tr, m = (l + r) >> 1;ans = min(min_dist(a, s, l, m), min_dist(a, s, m, r));for (tl = l; a[s[tl]].x < a[s[m]].x - ans; tl++);for (tr = r - l; a[s[tr]].x > a[s[m]].x + ans; tr--);sort(s + tl, s + tr, cmpy);for (int q = tl; q < tr; q++)for (int w = q + 1; w < min(tr, q + 6); w++)ans = min(ans, (a[s[q]] - a[s[w]]).norm());sort(s + tl, s + tr, cmpx);return ans;}double Min_Dist(point a[], int s[], int n){for (int i = 0; i < n; i++)s[i] = i;sort(s, s + n, cmpx);return min_dist(a, s, 0, n);}int main(){#ifndef ONLINE_JUDGEfreopen("in", "rt", stdin);#endifwhile(scanf("%d", &n) == 1 && n){for (int i = 0; i < n; i++)a[i].input();memset(s, 0, sizeof(s));double ans = Min_Dist(a, s, n);printf("%.2lf\n", ans / 2.0);}return 0;}


原创粉丝点击