zoukankan      html  css  js  c++  java
  • BJWC2011 最小三角形

    传送门

    题目描述很清楚……虽然说要求的三角形不一定是三角形……

    这个题和平面最近点对看起来很像。考虑分治,对于当前处在中央的一个点,能更新答案的只有两种,第一种是用两个同在一侧的点与之更新,另一种是用两个异侧的点与之更新。同侧的我们递归下去分治就好了,而对于不同侧的,我们首先得到这时已经计算出来的最小值,根据三角形三边关系,能更新答案的必定是与中间点横坐标距离不超过d/2的点,我们把这些点取出来按照y排序,之后再把这些点之间,所有y的距离不超过d/2的点三重循环枚举更新答案即可。

    看一下代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<map>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define fr friend inline
    #define y1 poj
    #define mp make_pair
    #define pr pair<int,int>
    #define fi first
    #define sc second
    #define pb push_back
    #define B printf("Bug
    ");
    
    using namespace std;
    typedef long long ll;
    const int M = 200005;
    const double INF = 1e15;
    const double eps = 1e-7;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    struct node
    {
       double x,y;
       bool operator < (const node &g) const
       {
          return x < g.x;
       }
    }a[M];
    
    int n,f[M];
    
    inline double dis(const int &p, const int &q)
    {
       return sqrt((a[p].x - a[q].x) * (a[p].x - a[q].x) + (a[p].y - a[q].y) * (a[p].y - a[q].y));
    }
    
    inline double length(const int &p,const int &q,const int &u)
    {
       return dis(p,q) + dis(q,u) + dis(p,u);
    }
    
    bool cmp(const int &p,const int &q)
    {
       return a[p].y < a[q].y;
    }
    
    double merge(const int &l,const int &r)
    {
       if(r - l <= 1) return INF;
       if(r - l == 2) return length(l,l+1,r);
       int mid = (l+r) >> 1,cnt = 0,now = 1;
       double d = min(merge(l,mid),merge(mid,r));
       double cur = d / 2.0;
       rep(i,l,r) if(fabs(a[i].x - a[mid].x) <= cur) f[++cnt] = i;
       sort(f+1,f+1+cnt,cmp);
       rep(i,1,cnt)
       {
          while(fabs(a[f[now]].y - a[f[i]].y) <= cur && now <= cnt) now++;
          rep(j,i+1,now-1)
          rep(k,j+1,now-1) d = min(d,length(f[i],f[j],f[k]));
       }
       return d;
    }
    
    int main()
    {
       n = read();
       rep(i,1,n) scanf("%lf%lf",&a[i].x,&a[i].y);
       sort(a+1,a+1+n);
       printf("%.6lf
    ",merge(1,n));
       return 0;
    }
    View Code
  • 相关阅读:
    array与xml转换实现(转)
    设计模式之: 策略模式
    设计模式之: 代理模式
    设计模式之: 状态模式
    dedecms分页
    dedecms导出csv文件
    假如项目中使用到了多 表查询,怎么办?
    git忽略某个文件夹
    git忽略某个文件
    无极限分类
  • 原文地址:https://www.cnblogs.com/captain1/p/10086595.html
Copyright © 2011-2022 走看看