求n个点的最小包围正方形。
对于其中的任意两个点构成一条边,
包围这条边 的正方形的边长,分析易得, 随着这条边的旋转角度的变化是 下凸曲线 ( 先下降后上升 ) 。
然而 对于 n*(n-1) 条边的状态和, 对于 旋转角度 x ,所有边的状态和 是 求max (分析易得)。
所以 n 的下凸曲线 的max 构成的曲线 还是下凸曲线。
因此对于所有的点 通过旋转 求的面积 满足三分。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <cstring>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <assert.h>
#include <queue>
#define REP(i,n) for(int i=0;i<n;i++)
#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define ALLL(x) x.begin(),x.end()
#define SORT(x) sort(ALLL(x))
#define CLEAR(x) memset(x,0,sizeof(x))
#define FILLL(x,c) memset(x,c,sizeof(x))
using namespace std;
const double eps = 1e-9;
#define LL long long
#define pb push_back
const int maxn = 110;
double x[maxn];
double y[maxn];
int n ;
double get_ans(double aaa){
double up,down;
double left,right;
for(int i=1;i<= n;i++){
double a = cos(aaa)*x[i] - sin(aaa)*y[i];
double b = cos(aaa)*y[i] + sin(aaa)*x[i];
// cout << x[i] << " "<< y[i] << " "<< a << " " << b<<endl;
if(i==1){
up = down = a;
left = right = b;
}else{
up = max(up,a);
down = min(down,a);
left= min(left ,b);
right= max(right,b);
}
}
double ret = max(right - left ,up - down);
// cout << ret << endl ;
return ret*ret;
}
void solve(){
double left = 0;
double right = acos(-1)/2;
int t = 300;
double ans ;
while(t--){
double k = (right - left)/3;
double lmid = left +k;
double rmid = left + 2* k;
double lans = get_ans(lmid);
double rans = get_ans(rmid);
ans = min(lans,rans);
if(get_ans(lmid)<get_ans(rmid)){
right = rmid ;
}else{
left = lmid;
}
}
// cout << ans <<endl ;
printf("%.2f\n",ans);
}
int main(){
int t;
cin >>t ;
while(~scanf("%d",&n),t--){
for(int i=1;i<=n;i++){
scanf("%lf%lf",&x[i],&y[i]);
}
//cout << get_ans(45);
solve();
}
return 0;
}