链接~
大意是说已知一堆点,求最小能覆盖全部点的正方形面积
这次练习赛的最难得题。。。木有思路,据说是三分,想半天用什么作为三分的依据→ →联想到之前建立基站的题,还以为是用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; }