1 条题解

  • 0
    @ 2025-5-25 17:16:13

    这段代码解决的是"最小外接正方形"问题,核心是通过旋转坐标轴找到能覆盖所有点的最小正方形。

    算法原理

    问题分析:给定平面上的n个点,求能覆盖所有点的最小正方形面积,正方形可以倾斜。

    关键思路旋转坐标轴:通过旋转坐标系,将问题转化为寻找某个旋转角度使得点集在新坐标系下的轴向外接矩形最小。 三分法优化:利用函数的单峰性(凸函数),使用三分法快速找到最优旋转角度。

    数学原理坐标旋转公式:将点(x,y)绕原点旋转θ角度后的新坐标为(x'=x·cosθ-y·sinθ, y'=x·sinθ+y·cosθ)。 正方形判定:当轴向外接矩形的长和宽相等时,其面积即为最小正方形面积。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    double eps=1e-12;
    const int N=50;
    #define INF 1e9
    const double pi=acos(-1.0);
    struct po{double x,y;}a[N];
    double maxx,maxy,minx,miny;int n;
    double bc(double j)
    {
    	double x,y;
    	maxx=maxy=-INF;
    	minx=miny=INF;
    	for (int i=1;i<=n;i++) 
    	{
    		x=a[i].x*cos(j)-a[i].y*sin(j);
    		y=a[i].x*sin(j)+a[i].y*cos(j);
    		maxx=max(maxx,x);
    		minx=min(minx,x);
    		maxy=max(maxy,y);
    		miny=min(miny,y);
    	}
    	return max(maxx-minx,maxy-miny);
    }
    int main()
    {
    	int T;scanf("%d",&T);
    	while (T--)
    	{
    		scanf("%d",&n);
    		for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    		double l=0,r=pi/2,m1,m2;
    		while (r-l>=eps)
    		{
    			m1=l+(r-l)/3;
    			m2=r-(r-l)/3;
    			if (bc(m1)<bc(m2)) r=m2;
    			else l=m1; 
    		}
    		l=bc(l);
    		printf("%.2lf\n",l*l);
    	}
    }
    
    • 1

    信息

    ID
    2302
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    1
    已通过
    1
    上传者