POJ 3301三分

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

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

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

#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxl 301
#define eps 1e-8
#define inf 2000000001

using 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;
			else
				l=mid;
		}
		printf("%.2f\n",t1*t1);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值