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

    题目描述 Description

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

    输入描述 Input Description

    第一行包含一个整数N表示点的个数。接下来N行每行有两个整数,表示这个点的坐标。

    输出描述 Output Description

    输出只有一行,包含一个6位小数,为周长最短的三角形的周长(四舍五入)。

    样例输入 Sample Input

    4

    1 1

    2 3

    3 3

    3 4

    样例输出 Sample Output

    3.414214

    数据范围及提示 Data Size & Hint

     

    之前的一些废话:是时候准备会考了。。

    题解:做法类似平面上求最近点对。首先把平面划分成两个部分,递归求出两个部分的答案为ans,然后,把离分割线距离小于ans/2的点全部加入队列,因为只有在这范围内答案才有可能比ans小,加入之后按照y坐标排一遍序,然后滑动窗口维护一下高度为ans/2的一个矩形,然后对矩形内的点暴力选,更新最优解即可。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long LL;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef pair<double,int> PDI;
    const int maxn=200010;
    const double oo=2147483647;
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct Point
    {
        double x,y;
        Point() {}
        Point(double _1,double _2):x(_1),y(_2){}
        bool operator < (const Point &s)const
        {
            if(x==s.x)return y<s.y;
            return x<s.x;
        }
    }p[maxn];
    int n;double x,y;
    PDI s[maxn];
    double dis(double a,double b,double c,double d){
        return sqrt((c-a)*(c-a)+(d-b)*(d-b));
    }
    double triangle_perimeter(double a,double b,double c,double d,double e,double f){
        return dis(a,b,c,d)+dis(a,b,e,f)+dis(c,d,e,f);
    }
    bool cmp(PDI a,PDI b){return a.first<b.first;} 
    double mdis(int l,int r)
    {
        if(l+1>=r)return oo;
        if(l+2==r)return triangle_perimeter(p[l].x,p[l].y,p[l+1].x,p[l+1].y,p[r].x,p[r].y);
        int mid=(l+r)>>1,t=0;
        double d=min(mdis(l,mid),mdis(mid,r));
        for(int i=l;i<=r;i++)if(fabs(p[i].x-p[mid].x)<=d/2.0)s[t++]=make_pair(p[i].y,i); 
        sort(s,s+t,cmp);
        int st=0,ed;
        while(st<=t-2)
        {
            ed=st+1;
            while(fabs(s[ed].first-s[st].first)<=(d/2.0) && ed<=t-2)ed++;
            for(int i=st+1;i<ed;i++)for(int j=i+1;j<ed;j++)
                d=min(d,triangle_perimeter(p[s[st].second].x,p[s[st].second].y,p[s[i].second].x,p[s[i].second].y,p[s[j].second].x,p[s[j].second].y)); 
            st++;
        }
        return d;
    }
    int main()
    {
        n=read();
        for(int i=0;i<n;i++)x=(double)read(),y=(double)read(),p[i]=Point(x,y);
        sort(p,p+n);
        printf("%.6lf
    ",mdis(0,n-1));
        return 0;
    }
    View Code

    总结:滑动窗口好难写。

  • 相关阅读:
    D. Longest Subsequence
    线段树入门HDU_1754
    poj_2503(map映射)
    HDU_4826
    poj_2251
    day 44 单表查询,多表查询
    day43 字段的修改、添加和删除,多表关系(外键),单表详细操作(增删改查)
    day 42 数据库的配置、数据库与表的一些剩余操作、用户操作、数据库表的引擎、数据库的模式、mysql支持的数据类型、约束
    day41 数据库介绍、数据库基本操作
    day 40 线程队列、线程定时器、进程池和线程池、同步与异步、用多线程来写socket服务端与客户端
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/7061175.html
Copyright © 2011-2022 走看看