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

    题目大意:给出平面上n个点,求最小的由这些点组成的三角形的周长。(N<=200,000)

    思路:点按x坐标排序后分治,每次取出与排在中间的点的横坐标相差不超当前答案一半的点,按y坐标排序后再暴力枚举y坐标相差不超过当前答案一半的三个点统计答案,复杂度O(能过)(听说期望nlogn)。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int x,f=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=-1;
        for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
        return x*f;
    }
    #define MN 200000
    double ans=1e18;
    struct P{int x,y;}p[MN+5],t[MN+5];
    bool cmpx(P a,P b){return a.x<b.x;}
    bool cmpy(P a,P b){return a.y<b.y;}
    double sqr(double x){return x*x;}
    double len(P a,P b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
    void solve(int l,int r)
    {
        if(r-l<2)return;
        int m=l+r>>1,i,j,k,cnt=0;
        solve(l,m);solve(m+1,r);
        for(i=l;i<=r;++i)if(fabs(p[i].x-p[m].x)<ans/2)t[++cnt]=p[i];
        sort(t+1,t+cnt+1,cmpy);
        for(i=1;i<=cnt;++i)for(j=i+1;j<=cnt&&t[j].y-t[i].y<ans/2;++j)for(k=j+1;k<=cnt&&t[k].y-t[i].y<ans/2;++k)
            ans=min(ans,len(t[i],t[j])+len(t[j],t[k])+len(t[k],t[i]));
    }
    int main()
    {
        int n=read(),i;
        for(i=1;i<=n;++i)p[i].x=read(),p[i].y=read();
        sort(p+1,p+n+1,cmpx);
        solve(1,n);
        printf("%.6lf",ans);
    }
  • 相关阅读:
    Java 多线程系列02
    Java 多线程系列01
    java io流03 字符流
    java JDBC系列
    java io流02 字节流
    Helidon使用心得
    camel 解析
    Spring 源码分析
    java代码实现分页功能
    SpringBoot Tomcat启动报错
  • 原文地址:https://www.cnblogs.com/ditoly/p/BZOJ2458.html
Copyright © 2011-2022 走看看