zoukankan      html  css  js  c++  java
  • bzoj1069: [SCOI2007]最大土地面积

    真搞笑,网上的人太能带节奏了,还以为是旋转卡(qia ka)壳(ke qiao)

    凸包完了直接暴力枚举对角的两个点,然后相当于两个区间分别找一个令和对角线组成的三角形最大的点,有单调性不用扫直接O(1)了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const double eps=1e-8;
    double sqr(double x){return x*x;}
    
    struct point{double x,y;}p[2100];
    double dis(point p1,point p2){return sqrt(sqr(p1.x-p2.x)+sqr(p1.y-p2.y));}
    double multi(point p1,point p2,point p0)
    {
        int x1,y1,x2,y2;
        x1=p1.x-p0.x;
        y1=p1.y-p0.y;
        x2=p2.x-p0.x;
        y2=p2.y-p0.y;
        return x1*y2-x2*y1;
    }
    
    int n;
    bool cmp(point p1,point p2)
    {
        double d=multi(p1,p2,p[1]);
        if(fabs(d)<=eps)return dis(p1,p[1])<dis(p2,p[1]);
        else return d>0;
    }
    int top,sta[1100000];
    void graham()
    {
        sort(p+2,p+n+1,cmp);
        top=0;sta[++top]=1,sta[++top]=2;
        double g;
        for(int i=3;i<=n;i++)
        {
            while(top>=2)
            {
                g=multi(p[sta[top]],p[i],p[sta[top-1]]);
                if(g<0||fabs(g)<=eps)top--;
                else break;
            }
            sta[++top]=i;
        }
    }
    int MOD(int x){return (x-1)%top+1;}
    double rch()
    {
        double ans=0;int a,b;
        for(int i=1;i<=top-2;i++)
        {
            a=MOD(i+1),b=MOD(i+3);
            for(int j=i+2;j<=top;j++)
            {
                while(MOD(a+1)!=j&&multi(p[sta[i]],p[sta[a]],p[sta[j]])<multi(p[sta[i]],p[sta[MOD(a+1)]],p[sta[j]]))a=MOD(a+1);
                while(MOD(b+1)!=i&&multi(p[sta[j]],p[sta[b]],p[sta[i]])<multi(p[sta[j]],p[sta[MOD(b+1)]],p[sta[i]]))b=MOD(b+1);
                ans=max(ans,(multi(p[sta[a]],p[sta[j]],p[sta[i]])+multi(p[sta[b]],p[sta[i]],p[sta[j]]))/2.0);
            }
        }
        printf("%.3lf
    ",ans);
    }
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&p[i].x,&p[i].y);
            if(p[i].y<p[1].y||(p[i].y==p[1].y&&p[i].x<p[1].x))
                swap(p[i],p[1]);
        }
        graham();
        rch();
        
        return 0;
    }
  • 相关阅读:
    elemeng-ui中el-select的默认选择项问题
    element-ui的rules中正则表达式
    时间戳格式化
    array排序(按数组中对象的属性进行排序)
    vue-router路由传参
    flex属性flex-grow、flex-shrink、flex-basis
    sessionStorage、localStorage与cookie
    并发编程学习之线程可见性
    JVM系列文章合集
    JVM(1):Java 类的加载机制
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10269121.html
Copyright © 2011-2022 走看看