BZOJ-1069: [SCOI2007]最大土地面积(旋转卡壳

作者: AmadeusChan | 来源:发表于2019-02-28 14:16 被阅读0次

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1069

先做出凸包,然后顺时针枚举对角线,我们就发现四边形的另外两个相对的点在顺时针方向上是递增的,于是乎就O( n^2 )可以AC了。。

代码:

#include <cstdio>

#include <algorithm>

#include <cstring>

#include <cmath>

 

using namespace std ;

 

#define rep( i , l , r ) for ( int i = l ; i <= r ; ++ i )

 

const double esp = 1e-8 ;

const int maxn = 2010 ;

 

struct Point {

    double x , y ;

    void read(  ) {

        scanf( "%lf%lf" , &x , &y ) ;

    }

    void print(  ) {

        printf( "( %.2f , %.2f )\n" , x , y ) ;

    }

} ;

 

struct Vector {

    double x , y ;

} ;

 

double operator * ( const Vector &x , const Vector &y ) {

    return x.x * y.y - y.x * x.y ;

}

 

Vector operator - ( const Point &x , const Point &y ) {

    return ( Vector ) { x.x - y.x , x.y - y.y } ;

}

 

double cmp( double x , double y ) {

    return ( x - y ) < - esp ? -1 : ( x - y ) > esp ;

}

 

bool cmp0( Point x , Point y ) {

    return cmp( x.y , y.y ) == 1 || ( ! cmp( x.y , y.y ) && cmp( x.x , y.x ) == - 1 ) ;

}

 

bool cmp1( Point x , Point y ) {

    return cmp( x.y , y.y ) == - 1 || ( ! cmp( x.y , y.y ) && cmp( x.x , y.x ) == 1 ) ;

}

 

Point p[ maxn ] , P[ maxn ] ;

int n , m = 0 ;

 

Point S[ maxn ] ;

int Top ;

 

double cal( Point a , Point b , Point c ) {

    return abs( ( ( a - c ) * ( b - c ) ) ) / 2.0 ;

}

 

int main(  ) {

    scanf( "%d" , &n ) ;

    rep( i , 1 , n ) p[ i ].read(  ) ;

    sort( p + 1 , p + n + 1 , cmp0 ) ;

    Top = 0 ;

    rep( i , 1 , n ) {

        while ( Top > 1 ) if ( cmp( ( S[ Top ] - S[ Top - 1 ] ) * ( p[ i ] - S[ Top - 1 ] ) , 0 ) != - 1 ) -- Top ; else break ;

        S[ ++ Top ] = p[ i ] ;

    }

    rep( i , 1 , Top ) P[ ++ m ] = S[ i ] ;

    sort( p + 1 , p + n + 1 , cmp1 ) ;

    Top = 0 ;

    rep( i , 1 , n ) {

        while ( Top > 1 ) if ( cmp( ( S[ Top ] - S[ Top - 1 ] ) * ( p[ i ] - S[ Top - 1 ] ) , 0 ) != - 1 ) -- Top ; else break ;

        S[ ++ Top ] = p[ i ] ;

    }

    rep( i , 2 , Top - 1 ) P[ ++ m ] = S[ i ] ;

    rep( i , 1 , m )  P[ m + i ] = P[ i ] ;

    double ans = 0 ;

    rep( i , 1 , m ) {

        int l = i + 1 , r = i + 3 ;

        rep( j , i + 2 , m ) {

            for ( ; cal( P[ i ] , P[ j ] , P[ l ] ) <= cal( P[ i ] , P[ j ] , P[ l + 1 ] ) ; ++ l ) ;

            for ( ; cal( P[ i ] , P[ j ] , P[ r ] ) <= cal( P[ i ] , P[ j ] , P[ r + 1 ] ) ; ++ r ) ;

            ans = max( ans , cal( P[ i ] , P[ j ] , P[ l ] ) + cal( P[ i ] , P[ j ] , P[ r ] ) ) ;

        }

    }

    printf( "%.3f\n" , ans ) ;

    return 0 ; 

}

相关文章

  • BZOJ-1069: [SCOI2007]最大土地面积(旋转卡壳

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1069 先...

  • 凸包(旋转卡壳)

    计算几何模板 旋转卡壳: 题目链接:面积最大的三角形 旋转卡壳:

  • 旋转卡壳(入门)

    旋(xuán)转(zhuàn)卡(qia)壳(qiào) 旋转卡壳可以用于求凸包的直径、宽度,两个不相交凸包间的最...

  • 旋转卡壳(一)

    1 .最小面积外接矩形 类似的,要求得外接矩形,则要求出矩形的宽和高,而高的求法已经知道了,是利用叉积求面积的方法...

  • 8.24 - hard - 105

    587. Erect the Fence 利用一种算法叫做Monotone Chain,加上之前的旋转卡壳。。。还...

  • 俄罗斯之行

    这次暑假我和姥姥、姥爷一起去了世界土地面积最大的俄罗斯。 第一天,我们去了俄罗斯的首都莫斯科。来到...

  • 卡壳

    前段时间写的文字都是生活的日记,想写点益他的文章,苦于没有找到好的方向,所以我不得不扩大阅读来扩充我枯竭的心灵。这...

  • 卡壳

    下面我要讲的故事是真实的,没有一处细节虚构,写实到近乎荒诞。因其真实,读起来可能有点压抑。原本想以旁观者的...

  • 卡壳

    一下子日更做什么?卡壳壳了,写不出来总不能扯草凑篮吧?好吧?就扯点狗尾巴花儿凑一下篮,总比没有日更好? 辛辛苦苦的...

  • 卡壳

    今天我坐了一上午一个字没有写,那种感觉就是大山里的汉子憋到了中年才娶上媳妇,自此日夜辛勤劳作在炕上。一段时间以后他...

网友评论

    本文标题:BZOJ-1069: [SCOI2007]最大土地面积(旋转卡壳

    本文链接:https://www.haomeiwen.com/subject/nrbhuqtx.html