zoukankan      html  css  js  c++  java
  • bzoj2458: [BeiJing2011]最小三角形

    题目描述:

    $Xaviera$ 现在遇到了一个有趣的问题。
    平面上有 $N$ 个点,$Xaviera$ 想找出周长最小的三角形。
    由于点非常多,分布也非常乱,所以 $Xaviera$ 想请你来解决这个问题。
    为了减小问题的难度,这里的三角形也包括共线的三点。

    算法标签:分治

    思路:

    每次不断分治下去,每一维只需要对于两区间最靠近中间仍有可能小于现有答案的部分进行统计。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define db double
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=2e5+5;
    const db eps=1e-8;
    int n,b[N],cnt;
    db ans;
    struct node{
        int x,y;
    }t[N];
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    bool cmp(node t1,node t2){
        return t1.x<t2.x;
    }
    bool cmp1(int t1,int t2){
        return t[t1].y<t[t2].y;
    }
    il db pf(db x){
        return x*x;
    }
    il db dis(int a,int b){
        return sqrt(pf(t[a].x-t[b].x)+pf(t[a].y-t[b].y));
    }
    il void solve(int l,int r){
        if(l==r)return;
        int mid=(l+r)>>1;
        solve(l,mid);solve(mid+1,r);
        cnt=0;b[++cnt]=mid;
        for(int i=mid-1;i>=l;i--)if(t[mid].x-t[i].x<ans)b[++cnt]=i;else break;
        for(int i=mid+1;i<=r;i++)if(t[i].x-t[mid].x<ans)b[++cnt]=i;else break;
        sort(b+1,b+1+cnt,cmp1);
        long double dis1,dis2,dis3;
        for(int i=1;i<cnt-1;i++){
            for(int j=i+1;j<cnt;j++){
                if(t[b[j]].y-t[b[i]].y>ans)break;
                dis1=dis(b[i],b[j]);
                if(dis1>ans)continue;
                for(int k=j+1;k<=cnt;k++){
                    if(t[b[k]].y-t[b[j]].y>ans)break;
                    dis2=dis(b[i],b[k]);
                    if(dis2>ans)continue;
                    dis3=dis(b[j],b[k]);
                    if(dis1+dis2+dis3<ans)ans=dis1+dis2+dis3;
                }
            }
        }
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)t[i].x=read(),t[i].y=read();
        sort(t+1,t+1+n,cmp);
        ans=dis(1,2)+dis(1,3)+dis(2,3);
        solve(1,n);
        printf("%lf
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    前端调用后台接口下载word文档的两种方法
    Layui form表单提交注意事项
    JavaScript_Util_01
    心理
    小例子
    SQL分割字符串
    绘制10种不同颜色的散点图
    绘制散点图
    subplot的使用
    绘制正弦余弦
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10481058.html
Copyright © 2011-2022 走看看