zoukankan      html  css  js  c++  java
  • 【BZOJ】【1069】【SCOI2007】最大土地面积

    计算几何/旋转卡壳


      从已知点中选出四个使得选出的四边形面积最大,很明显我们应该在凸包上搞。

      我一开始的思路是:枚举 i ,找到 i 的对锺点cur1,这两个点将凸包分成了两半,我们在左半中枚举一个 j ,然后在右半中找一个离 j 最远的“对锺点”(可能不是?反正找的是最远……)cur2,然后求cur1和cur2都是单调的,复杂度为枚举 i, j的$O(n^2)$

      然而跪了= =然后我去Orz了proverbs的题解,得到启示:我们可以枚举一条对角线,然后在左半和右半中各找一条跟这条对角线最远的点!这两个点的寻找明显是单调的,复杂度为枚举对角线的两个端点的$O(n^2)$

      Orzzzzz思路还是不够开阔啊

      一开始错我还以为是旋转卡壳写错了……后来发现原来是凸包写错了QAQ

     1 /**************************************************************
     2     Problem: 1069
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:284 ms
     7     Memory:1340 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1069
    11 #include<cmath>
    12 #include<cstdio>
    13 #include<cstring>
    14 #include<cstdlib>
    15 #include<iostream>
    16 #include<algorithm>
    17 #define rep(i,n) for(int i=0;i<n;++i)
    18 #define F(i,j,n) for(int i=j;i<=n;++i)
    19 #define D(i,j,n) for(int i=j;i>=n;--i)
    20 #define pb push_back
    21 using namespace std;
    22 typedef long long LL;
    23 inline int getint(){
    24     int r=1,v=0; char ch=getchar();
    25     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
    26     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
    27     return r*v;
    28 }
    29 const int N=2010;
    30 /*******************template********************/
    31 struct Poi{
    32     double x,y;
    33     Poi(){}
    34     Poi(double x,double y):x(x),y(y){}
    35     void read(){scanf("%lf%lf",&x,&y);}
    36 }p[N],ch[N];
    37 typedef Poi Vec;
    38 Vec operator - (const Poi &a,const Poi &b){return Vec(a.x-b.x,a.y-b.y);}
    39 bool operator < (const Poi &a,const Poi &b){return a.x<b.x || (a.x==b.x && a.y<b.y);}
    40 inline double Dot(const Poi &a,const Poi &b){return a.x*b.x+a.y*b.y;}
    41 inline double Cross(const Poi &a,const Poi &b){return a.x*b.y-a.y*b.x;}
    42  
    43 int n,m;
    44 double ans;
    45 void graham(Poi *p,int n){
    46     sort(p+1,p+n+1);
    47     ch[++m]=p[1];
    48     F(i,2,n){
    49         while(m>1 && Cross(ch[m]-ch[m-1],p[i]-ch[m-1])<=0) m--;
    50         ch[++m]=p[i];
    51     }
    52     int k=m;
    53     D(i,n-1,1){
    54         while(m>k && Cross(ch[m]-ch[m-1],p[i]-ch[m-1])<=0) m--;
    55         ch[++m]=p[i];
    56     }
    57     if (n>1) m--;
    58 }
    59 double getans(Poi a1,Poi a2,Poi b1,Poi b2){
    60     return Cross(a2-a1,b1-a1)+Cross(b2-b1,a1-b1);
    61 }
    62 void rot(Poi *p,int n){
    63     int cur1=2,cur2,j;
    64     F(i,1,n) p[i+n]=p[i];
    65     F(i,1,n-1){
    66         cur1=i+1;
    67         j=cur1+1;
    68         cur2=j+1;
    69         for(;j<i+n-1;j++){
    70             while(Cross(p[cur1+1]-p[i],p[j]-p[i]) > Cross(p[cur1]-p[i],p[j]-p[i]))
    71                 cur1=cur1%n+1;
    72             while(Cross(p[cur2+1]-p[j],p[i]-p[j]) > Cross(p[cur2]-p[j],p[i]-p[j])){
    73                 cur2=cur2%n+1;
    74                 if (cur2>=i+n-1) break;
    75             }
    76             if (cur2>i+n-1) break;
    77             ans=max(ans,getans(p[i],p[cur1],p[j],p[cur2]));
    78         }
    79     }
    80 }
    81 int main(){
    82 #ifndef ONLINE_JUDGE
    83     freopen("1069.in","r",stdin);
    84 //  freopen("1069.out","w",stdout);
    85 #endif
    86     n=getint();
    87     F(i,1,n) p[i].read();
    88     graham(p,n);
    89     rot(ch,m);
    90     printf("%.3f
    ",ans*0.5);
    91     return 0;
    92 }
    View Code

    1069: [SCOI2007]最大土地面积

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 1853  Solved: 683
    [Submit][Status][Discuss]

    Description

    在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大。

    Input

    第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。

    Output

    最大的多边形面积,答案精确到小数点后3位。

    Sample Input

    5
    0 0
    1 0
    1 1
    0 1
    0.5 0.5

    Sample Output

    1.000

    HINT

    数据范围 n<=2000, |x|,|y|<=100000

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    我所知道的JS调试
    css加载会造成阻塞吗?
    移动端图片上传旋转、压缩的解决方案
    JS组件系列——自己动手扩展BootstrapTable的 冻结列 功能:彻底解决高度问题
    什么是BFC
    CSS中margin边界叠加问题及解决方案
    JavaScript 中回调地狱的今生前世
    用css实现自定义虚线边框
    仿淘宝,京东红包雨
    css3实现可以计算的自适应布局——calc()
  • 原文地址:https://www.cnblogs.com/Tunix/p/4501122.html
Copyright © 2011-2022 走看看