zoukankan      html  css  js  c++  java
  • POJ 3714 Raid(平面近期点对)

    解题思路:

    分治法求平面近期点对。点分成两部分,加个标记就好了。

    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #include <iomanip>
    #include <string.h>
    #define LL long long
    using namespace std;
    const int MAXN = 200000 + 10;
    const double INF = 1e100;
    struct Point
    {
        double x, y;
        int flag;
    }P[MAXN];
    int N;
    Point vec[MAXN];
    bool cmp_x(Point a, Point b)
    {
        return a.x < b.x;
    }
    bool cmp_y(Point a, Point b)
    {
        return a.y < b.y;
    }
    double dis(Point a, Point b)
    {
        double dx = a.x - b.x;
        double dy = a.y - b.y;
        return sqrt(dx * dx + dy * dy);
    }
    double solve(Point *a, int l, int r)
    {
        if(l == r) return INF;
        if(l + 1 == r)
        {
            if(P[l].flag == P[r].flag)
                return INF;
            return dis(P[l], P[r]);
        }
        int m = (l + r) >> 1;
        double d = solve(a, l, m);
        d = min(d, solve(a, m + 1, r));
        int sz = 0;
        for(int i=l;i<=r;i++)
        {
            if(fabs(P[i].x - P[m].x) <= d)
                vec[sz++] = P[i];
        }
        sort(vec, vec + sz, cmp_y);
        for(int i=0;i<sz;i++)
        {
            for(int j=i+1;j<sz;j++)
            {
                if(fabs(vec[i].y - vec[j].y) >= d)
                    break;
                if(vec[i].flag != vec[j].flag)
                {
                    double rs = dis(vec[i], vec[j]);
                    if(rs < d) d = rs;
                }
            }
        }
        return d;
    }
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &N);
            for(int i=0;i<N;i++)
            {
                scanf("%lf%lf", &P[i].x, &P[i].y);
                P[i].flag = 0;
            }
            for(int i=0;i<N;i++)
            {
                scanf("%lf%lf", &P[i + N].x, &P[i + N].y);
                P[i + N]. flag = 1;
            }
            N <<= 1;
            sort(P, P + N, cmp_x);
            double ans = solve(P, 0, N - 1);
            printf("%.3f
    ", ans);
        }
        return 0;
    }
    

  • 相关阅读:
    代理模式
    spring aop
    mybatis从入门到精通(其他章节)
    mybatis从入门到精通(第6章)
    Java中Compareable和Comparator两种比较器的区别
    Java的equals方法的使用技巧
    Dubbo的配置过程,实现原理及架构详解
    什么是IPFS?IPFS与区块链有什么关系
    leetCode242 有效的字母异位词
    需要多个参数输入时-----------------考虑使用变种的Builder模式
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7272365.html
Copyright © 2011-2022 走看看