POJ 3301 三分

给出许多点的坐标,用最小的正方形覆盖之。

1、 边长一定为某2点距离

2、 假如正方形平行于x轴与y轴, 如果只算xy轴方向的距离。

       那么只需找最远的 max(|xi - xj| ,  |yi-yj|) ; 

3、将N个点绕(0,0)旋转alfa弧度。这个时候 |xi - xj|会变小再变大

const    int  maxn = 38  ;
const    double  inf = 1<<30 ;
double   px[maxn] , py[maxn] ;
int      n ;

double   f(double alfa){
         double  xi  , yi  , xj , yj  , r = -inf ;
         for(int i = 1 ; i <= n ; i++){
             for(int j = i+1 ; j <= n ; j++){
                  xi = cos(alfa) * px[i] - sin(alfa) * py[i] ;
                  yi = sin(alfa) * px[i] + cos(alfa) * py[i] ;
                  xj = cos(alfa) * px[j] - sin(alfa) * py[j] ;
                  yj = sin(alfa) * px[j] + cos(alfa) * py[j] ;
                  r = max(r , fabs(xi-xj)) ;
                  r = max(r , fabs(yi-yj)) ;
             }
         }
         return  r;
}

const    double  eps = 1e-12 ;
double   ts(){
         double l , r , mid , midmid  , mdf , mmdf ;
         l = 0 , r = acos(-1.0) ;
         while(l + eps < r){
               mid = (l + r) * 0.5 ;
               midmid = (mid + r) * 0.5 ;
               mdf = f(mid) ;
               mmdf = f(midmid) ;
               if(mdf <= mmdf)  r = midmid ;
               else             l = mid ;
         }
         return  f( mid ) ;
}

int main(){
    int  t , i  ;
    cin>>t ;
    while(t--){
         cin>>n ;
         for(i = 1 ; i <= n ; i++) scanf("%lf%lf" , &px[i] , &py[i])  ;
         double x = ts() ;
         printf("%.2lf\n" , x * x) ;
    }
    return 0;
}


你可能感兴趣的:(POJ 3301 三分)