问题分析
假的题目,假的数据……
不可能有少于(O(n^2))的做法的,少于(O(n^2))的做法是不可能的。
然而由于假的数据,凸包上的点只有不到(3000)个,所以(n^2)就好了……
秘技是语言选C++而不是G++
参考程序
#include <cmath>
#include <algorithm>
#include <cstdio>
#define LL long long
using namespace std;
const LL Maxn = 50010;
struct point {
LL x, y;
point() {}
point( LL _x, LL _y ) : x( _x ), y( _y ) {}
inline point operator - ( const point Other ) const {
return point( x - Other.x, y - Other.y );
}
inline LL operator * ( const point Other ) const {
return x * Other.y - y * Other.x;
}
inline LL Dis() const { return x * x + y * y; }
};
LL N, M;
point A[ Maxn ], B[ Maxn ];
bool Cmp( const point X, const point Y ) {
return ( X - A[ 1 ] ) * ( Y - A[ 1 ] ) > 0 ||
( ( X - A[ 1 ] ) * ( Y - A[ 1 ] ) == 0 && ( X - A[ 1 ] ).Dis() < ( Y - A[ 1 ] ).Dis() );
}
int main() {
scanf( "%lld", &N );
while( N != -1 ) {
for( LL i = 1; i <= N; ++i ) scanf( "%lld%lld", &A[ i ].x, &A[ i ].y );
for( LL i = 2; i <= N; ++i )
if( A[ i ].y < A[ 1 ].y || ( A[ i ].y == A[ 1 ].y && A[ i ].x < A[ 1 ].x ) )
swap( A[ i ], A[ 1 ] );
sort( A + 2, A + N + 1, Cmp );
M = 1; B[ 1 ] = A[ 1 ];
for( LL i = 2; i <= N; ++i ) {
for( ; M > 1 && ( A[ i ] - B[ M - 1 ] ) * ( B[ M ] - B[ M - 1 ] ) >= 0; --M );
B[ ++M ] = A[ i ];
}
if( M <= 2 ) {
printf( "0.00
" );
scanf( "%lld", &N );
continue;
}
LL Ans = 0;
for( LL i = 1, j, k, l; i < M; ++i ) {
j = k = i + 1;
l = ( k + 1 > M ) ? 1 : k + 1;
for( ; ( B[ j ] - B[ i ] ) * ( B[ l ] - B[ k ] ) >= 0; k = l, l = ( k + 1 > M ) ? 1 : k + 1 );
Ans = max( Ans, ( B[ j ] - B[ i ] ) * ( B[ k ] - B[ i ] ) );
for( ; j <= M; ++j ) {
for( ; ( B[ j ] - B[ i ] ) * ( B[ l ] - B[ k ] ) >= 0; k = l, l = ( k + 1 > M ) ? 1 : k + 1 );
Ans = max( Ans, ( B[ j ] - B[ i ] ) * ( B[ k ] - B[ i ] ) );
}
}
printf( "%.2lf
", 0.5 * Ans );
scanf( "%lld", &N );
}
return 0;
}