【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; }