大意是说已知一堆点,求最小能覆盖全部点的正方形面积
这次练习赛的最难得题。。。木有思路,据说是三分,想半天用什么作为三分的依据→ →联想到之前建立基站的题,还以为是用x,y轴的坐标三分呢,想半天觉得半径没法表示,于是乎羞愧的搜题解,发现也没多难,只不过卡到了旋转这个点上其实也还好说,要是题干问平行于坐标轴的最小正方形面积,都会求;要是不必须平行于呢?一样啊
先求出来平行于坐标轴时最小面积,逐渐旋转,每次都是把个点的坐标投影到这个转了的轴上求最小面积
还要注意一点 g++虽说比c++快 double形式的格式输出不一样,就这样,华丽丽的wa了三次
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define eps 1e-9
using namespace std;
const int INF=0x3f3f3f3f;
double x[40],y[40];
int n;
double cal(double a)
{
double minx=INF,miny=INF,maxx=-INF,maxy=-INF,xx,yy;
for(int i=0;i<n;i++)
{
xx=cos(a)*x[i]-sin(a)*y[i];
yy=sin(a)*x[i]+cos(a)*y[i];
minx=min(minx,xx);
miny=min(miny,yy);
maxx=max(maxx,xx);
maxy=max(maxy,yy);
}
// cout<< "cal: "<<max((maxx-minx),(maxy-miny))<<endl;
return max((maxx-minx),(maxy-miny));
}
double solve(double l,double r)
{
double mid,midmid;
double d1,d2;
while(r-l>eps)
{
mid=(l+r)/2;
midmid=(mid+r)/2;
d1=cal(mid);
d2=cal(midmid);
if(d1<d2) r=midmid;
else l=mid;
}
return cal(l)*cal(l);
}
int main()
{
//freopen("cin.txt","r",stdin);
int t;
while(~scanf("%d",&t))
{
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lf%lf",&x[i],&y[i]);
printf("%0.2lf\n",solve(0,3.1415926));
}
}
return 0;
}