• 平面最近点对题目


    hdu 1007 Quoit Design 最近点模板题目

    题意:

    给你n个点求平面上任意两点的最短距离

    思路:

    平面最近点对距离模板题,见算法导论P591

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    
    #define lc l,m,rt<<1
    #define rc m + 1,r,rt<<1|1
    #define pi acos(-1.0)
    #define ll __int64
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d
    ", x)
    #define keyTree (chd[chd[root][1]][0])
    #define Read()  freopen("din.txt", "r", stdin)
    #define Write() freopen("dout.txt", "w", stdout);
    
    
    #define M 100007
    #define N 100007
    
    using namespace std;
    
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    
    const int inf = 0x7f7f7f7f;
    const int mod = 1000000007;
    
    const double eps = 1e-8;
    
    struct Point
    {
        double x,y;
    }pt[N];
    int a[N];
    
    int n;
    int  cmp(Point a, Point b)
    {
        if (a.x != b.x) return a.x < b.x;
        else return a.y < b.y;
    }
    int cmp_y(int a,int b)
    {
        return pt[a].y < pt[b].y;
    }
    double getDis(const Point &a, const Point &b)
    {
       double x = a.x - b.x;
       double y = a.y - b.y;
       return sqrt(x*x + y*y);
    }
    double solve(int l, int r)
    {
        double ans = 0;
        if (r - l + 1 <= 3)
        {
            if (r - l + 1 == 1) return ans;
            ans = getDis(pt[l], pt[l + 1]);
            if (r - l + 1 == 2) return ans;
            for (int i = l; i < r; ++i)
            {
                for (int j = i + 1; j <= r; ++j)
                {
                    ans = min(ans, getDis(pt[i],pt[j]));
                }
            }
            return ans;
        }
        int m = (l + r) >> 1;
        double s1 = solve(l, m);
        double s2 = solve(m + 1,  r);
        ans = min(s1,s2);
        int k = 0;
        for (int i = m - 1; i >= l && pt[m].x - pt[i].x <= ans; --i) a[k++] = i;
        for (int i = m + 1; i <= r && pt[i].x - pt[m].x <= ans; ++i) a[k++] = i;
        //sort(a, a + k, cmp_y);
        for (int i = 0; i < k; ++i)
        {
            for (int j = i + 1; j < k && j <= i + 7; ++j)
            {
                ans = min(ans, getDis(pt[a[i]], pt[a[j]]));
            }
        }
        return ans;
    }
    int main()
    {
        while (~scanf("%d",&n))
        {
            if (!n) break;
            for (int i = 0; i < n; ++i) scanf("%lf%lf",&pt[i].x, &pt[i].y);
            sort(pt, pt + n, cmp);
            printf("%.2lf
    ",solve(0, n - 1)/2.0);
        }
        return 0;
    }
    View Code

    Pku 3714 Raid 

    题意:

    给你n个A种点,n个B种点,求A种点中距离B种点最近的距离

    思路:

    还是平面最近点对模板的加强,就是判断一下只有点的种类不同才能计算距离

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    
    #define lc l,m,rt<<1
    #define rc m + 1,r,rt<<1|1
    #define pi acos(-1.0)
    #define ll __int64
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d
    ", x)
    #define keyTree (chd[chd[root][1]][0])
    #define Read()  freopen("din.txt", "r", stdin)
    #define Write() freopen("dout.txt", "w", stdout);
    
    
    #define M 100007
    #define N 100007
    
    using namespace std;
    
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    
    const double inf = 100000000000.0;
    const int mod = 1000000007;
    
    const double eps = 1e-8;
    
    struct Point
    {
        double x,y;
        int id;
    }pt[2*N];
    int a[2*N];
    
    int n;
    int  cmp(Point a, Point b)
    {
        if (a.x != b.x) return a.x < b.x;
        else return a.y < b.y;
    }
    int cmp_y(int a,int b)
    {
        return pt[a].y < pt[b].y;
    }
    double getDis(const Point &a, const Point &b)
    {
       if (a.id == b.id) return inf;
       double x = a.x - b.x;
       double y = a.y - b.y;
       return sqrt(x*x + y*y);
    }
    double solve(int l, int r)
    {
        double ans = inf;
        if (r - l + 1 <= 3)
        {
            for (int i = l; i < r; ++i)
            {
                for (int j = i + 1; j <= r; ++j)
                {
                    if (pt[i].id != pt[j].id)
                    ans = min(ans, getDis(pt[i], pt[j]));
                }
            }
            return ans;
        }
        int m = (l + r) >> 1;
        double s1 = solve(l, m);
        double s2 = solve(m, r);
        ans = min(s1,s2);
        int k = 0;
        for (int i = m - 1; i >= l && pt[m].x - pt[i].x <= ans; --i) a[k++] = i;
        for (int i = m + 1; i <= r && pt[i].x - pt[m].x <= ans; ++i) a[k++] = i;
        sort(a, a + k, cmp_y);
        for (int i = 0; i < k; ++i)
        {
            for (int j = i + 1; j < k && j <= i + 7; ++j)
            {
                if (pt[a[i]].id != pt[a[j]].id)
                ans = min(ans, getDis(pt[a[i]], pt[a[j]]));
            }
        }
        return ans;
    }
    int main()
    {
    
        int T;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);
            for (int i = 0; i < n; ++i) scanf("%lf%lf",&pt[i].x, &pt[i].y), pt[i].id = 0;
            for (int i = n; i < 2*n; ++i) scanf("%lf%lf",&pt[i].x, &pt[i].y), pt[i].id = 1;
            n *= 2;
            sort(pt, pt + n, cmp);
            printf("%.3lf
    ",solve(0, n - 1));
        }
        return 0;
    }
    View Code

    hdu 4631 Sad Love Story

    题意:

    向一个空的平面上加点,每次加入一点求该平面里面最近点对之间的距离的平方为s[i],求s[2] + s[3] + s[n]d的总和

    思路:

    贪心+最近点对

    首先我们求出整个平面加完n个点之后的最近点对i,j,pt[i].id表示i是第几个加入的, 那么在max(pt[i].id, pt[j].id)之后的点加进来的话肯定也是这个值,这样我们就省去了一大段的计算,然后进行了优化。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    
    #define lc l,m,rt<<1
    #define rc m + 1,r,rt<<1|1
    #define pi acos(-1.0)
    #define ll __int64
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d
    ", x)
    #define keyTree (chd[chd[root][1]][0])
    #define Read()  freopen("din.txt", "r", stdin)
    #define Write() freopen("dout.txt", "w", stdout);
    
    
    #define M 100007
    #define N 500007
    
    using namespace std;
    
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    
    const double inf = 100000000000.0;
    const int mod = 1000000007;
    
    struct Point
    {
        int x,y;
        int id;
    }pt[N],p[N];
    int a[N];
    int n;
    int Ax,Bx,Cx,Ay,By,Cy;
    
    int cmp(const Point &a, const Point &b)
    {
        if (a.x != b.x) return a.x < b.x;
        else return a.y < b.y;
    }
    int cmp_y(int a, int b)
    {
        return pt[a].y < pt[b].y;
    }
    ll getDis(const Point &a, const Point &b)
    {
        ll x = a.x - b.x;
        ll y = a.y - b.y;
        return x*x + y*y;
    }
    ll MinDis(int l,int r,int &top)
    {
        int len = r - l + 1;
        ll s3;
        if (len <= 3)
        {
            s3 = getDis(pt[l],pt[l + 1]);
            top = max(pt[l].id, pt[l + 1].id);
            if (len == 2) return s3;
            else
            {
                ll tmp = getDis(pt[l],pt[l + 2]);
                if (s3 > tmp) { s3 = tmp; top = max(pt[l].id, pt[l + 2].id); }
                tmp = getDis(pt[l + 1], pt[l + 2]);
                if (s3 > tmp) { s3 = tmp; top = max(pt[l + 1].id, pt[l + 2].id); }
            }
            return s3;
        }
        int m = (l + r) >> 1;
        int top1, top2;
        ll s1 = MinDis(l, m, top1);
        ll s2 = MinDis(m, r, top2);
    
        if (s1 < s2) { s3 = s1, top = top1; }
        else if (s1 > s2){ s3 = s2, top = top2; }
        else { s3 = s1, top = min(top1, top2); }
        int k = 0;
        for (int i = m - 1; i >= l && pt[m].x - pt[i].x <= s3; --i) a[k++] = i;
        for (int i = m + 1; i <= r && pt[i].x - pt[m].x <= s3; ++i) a[k++] = i;
        sort(a, a + k, cmp_y);
        for (int i = 0; i < k; ++i)
        {
            for (int j = i + 1; j < k && j <= i + 7; ++j)
            {
                ll tmp = getDis(pt[a[i]], pt[a[j]]);
                if (s3 > tmp)
                {
                    s3 = tmp;
                    top = max(pt[a[i]].id,pt[a[j]].id);
                }
            }
        }
        return s3;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d%d%d%d%d%d%d",&n,&Ax,&Bx,&Cx,&Ay,&By,&Cy);
            p[0].x = 0; p[0].y = 0;
            for (int i = 1; i <= n; ++i)
            {
                p[i].x = (ll)((ll)Ax*p[i - 1].x + Bx)%Cx;
                p[i].y = (ll)((ll)Ay*p[i - 1].y + By)%Cy;
                p[i].id = i;
            }
    
            ll sum = 0;
            while (n >= 2)
            {
                for (int i = 1; i <= n; ++i) pt[i] = p[i];
                sort(pt + 1, pt + 1 + n, cmp);
                int top = 0;
                ll tmp = MinDis(1,n,top);
                sum += (tmp * (n - top + 1));
                n = top - 1;
            }
            printf("%I64d
    ",sum);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Docker 文档编译
    Docker CentOS 安装方法
    Docker CentOS 安装要求
    Docsify 的文档页面标题在那里设置
    Docsify 的 GitHub 链接在那里设置的
    GitHub 中如何启用 GitHub Pages 中的子域名
    Spring API 的 CORS 测试 提示错误 Reason: header ‘authorization’ is not allowed
    Spring API 的 CORS 测试
    CentOS 7 安装 JDK 11
    Postman API 获得文件如何保存
  • 原文地址:https://www.cnblogs.com/E-star/p/3367090.html
Copyright © 2020-2023  润新知