思路:三分法求解凸函数的极值,三分法介绍在这:http://hi.baidu.com/czyuan_acm/item/81b21d1910ea729c99ce33db
很容易就可以推出旋转后的坐标:
x'=xcos(a)-ysin(a);
y'=ycos(a)+xsin(a).
cal(a)的意义就是在原来坐标上的点经过a弧度逆旋转后,正方形(边与坐标轴平行)最小边长要多长
cal()在旋转的时候符合凸函数,所以三分求最值
代码如下:
#include<iostream> #include<stdio.h> #include<algorithm> #include<iomanip> #include<cmath> #include<cstring> #include<vector> #define ll __int64 #define pi acos(-1.0) #define MAX 100000000 #define MIN -100000000 using namespace std; double x[31],y[31]; int n; double cal(double a) { double maxx=MIN,maxy=MIN,minx=MAX,miny=MAX,xx,yy; for(int i=0;i<n;i++){ xx=x[i]*cos(a)-y[i]*sin(a); yy=y[i]*cos(a)+x[i]*sin(a); maxx=max(xx,maxx); minx=min(xx,minx); maxy=max(yy,maxy); miny=min(yy,miny); } return max(maxx-minx,maxy-miny); } int main(){ int t,i; double l,r,mid,mmid,ans; cin>>t; while(t--){ cin>>n; for(i=0;i<n;i++) cin>>x[i]>>y[i]; l=0.0; r=pi; while(r-l>1e-8){ mid=(l+r)/2; mmid=(mid+r)/2; ans=cal(mid); if(ans<=cal(mmid)) r=mmid; else l=mid; } printf("%.2lf ",ans*ans); } return 0; }