POJ 3301三分

来源:互联网 发布:java程序设计教程 实验 编辑:程序博客网 时间:2024/05/17 09:02

大意:给N个点,用最小面积的正方形覆盖。

三分坐标轴旋转角度,然后在N个点中找最大边长。

坐标偏转后的点的变化公式可用极坐标方程证明。

#include<cstdio>#include<cmath>#include<algorithm>#define maxl 301#define eps 1e-8#define inf 2000000001using namespace std;int n,t;const double pi=acos(-1.0);struct node{double x,y;}a[maxl];/*记原点为O设ρ=OA=√x02+y02三角换元x0=ρcosθ,y0=ρsinθ其中cosθ=x0/ρ,sinθ=y0/ρ逆时针旋转n度后x=ρcos(θ+n)=ρ(cosθcosn-sinθsinn)=x0cosn-y0sinn同理y=ρsin(θ+n)=…=x0sinn+y0cosn*/double calc(double ang){double maxx=-inf,maxy=-inf,minx=inf,miny=inf;double tx,ty;for(int i=1;i<=n;i++){tx=a[i].x*cos(ang)-a[i].y*sin(ang);ty=a[i].y*cos(ang)+a[i].x*sin(ang);maxx=max(maxx,tx);maxy=max(maxy,ty);minx=min(minx,tx);miny=min(miny,ty);}return max(maxx-minx,maxy-miny);}int main(){double l,r,mid,midmid,t1,t2;scanf("%d",&t);for(int i=1;i<=t;i++){scanf("%d",&n);for(int j=1;j<=n;j++)scanf("%lf%lf",&a[j].x,&a[j].y);l=0;r=pi;while(l+eps<r){mid=(l+r)/2.0;midmid=(r+mid)/2.0;t1=calc(mid);t2=calc(midmid);if(t1<t2)r=midmid;elsel=mid;}printf("%.2f\n",t1*t1);}return 0;}


原创粉丝点击