【poj3301】【模板】最小正方形覆盖(坐标旋转加三分)

题目链接:https://vjudge.net/problem/POJ-3301

代码:

/*************************************************************************
    > File Name: poj3301.cpp
# File Name: poj3301.cpp
# Author : xiaobuxie
# QQ : 760427180
# Email:760427180@qq.com
# Created Time: 2019年10月23日 星期三 19时34分28秒
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
#include<cstring>
#include<set>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define eps 1e-8
const double pi = acos(-1.0);
int sgn(double x){
    if(fabs(x) < eps) return 0;
    if(x<0) return -1;
    return 1;
}
const int N = 49;
struct Point{
    double x,y;
    Point(){x=y=0;}
    Point(double a,double b){x=a,y=b;}
}p[N];
int n;
double cal(double u){
    double maxx,minx,maxy,miny;
    maxx = maxy = -inf;
    minx = miny = inf;
    //逆时针旋转
    for(int i = 1;i<=n;++i){
        double x = p[i].x*cos(u) - p[i].y*sin(u);
        double y = p[i].x*sin(u) + p[i].y*cos(u);
        maxx = max(maxx,x);
        maxy = max(maxy,y);
        minx = min(minx,x);
        miny = min(miny,y);
    }
    return max( maxx - minx,maxy - miny);
}
int main(){
    int T; scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i = 1;i <= n; ++i) scanf("%lf %lf",&p[i].x,&p[i].y);
        double l = 0,r = pi/2;
        //三分旋转角度
        while( r - l > eps){
            double mid1 = (l+r)/2.0;
            double mid2 = (mid1 + r)/2.0;
            if( cal(mid1) > cal(mid2) ) l = mid1;
            else r = mid2;
        }
        double ans = cal(l);
        printf("%.2f\n",ans*ans);
    }
    return 0;
}
View Code

 

posted @ 2019-10-23 19:49  小布鞋  阅读(168)  评论(0编辑  收藏  举报