poj3301Texas Trip三分旋转角度

链接~

大意是说已知一堆点,求最小能覆盖全部点的正方形面积

这次练习赛的最难得题。。。木有思路,据说是三分,想半天用什么作为三分的依据→ →联想到之前建立基站的题,还以为是用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;
}


你可能感兴趣的:(ACM,三分)