poj 3301 Texas Trip 三分法

思路:三分法求解凸函数的极值,三分法介绍在这:http://hi.baidu.com/czyuan_acm/item/81b21d1910ea729c99ce33db

很容易就可以推出旋转后的坐标:

x'=xcos(a)-ysin(a);

y'=ycos(a)+xsin(a).

cal(a)的意义就是在原来坐标上的点经过a弧度逆旋转后,正方形(边与坐标轴平行)最小边长要多长

cal()在旋转的时候符合凸函数,所以三分求最值

 

代码如下:

 

#include<iostream>

#include<stdio.h>

#include<algorithm>

#include<iomanip>

#include<cmath>

#include<cstring>

#include<vector>

#define ll __int64

#define pi acos(-1.0)

#define MAX 100000000

#define MIN -100000000

using namespace std;

double x[31],y[31];

int n;

double cal(double a)

{

    double maxx=MIN,maxy=MIN,minx=MAX,miny=MAX,xx,yy;

    for(int i=0;i<n;i++){

        xx=x[i]*cos(a)-y[i]*sin(a);

        yy=y[i]*cos(a)+x[i]*sin(a);

        maxx=max(xx,maxx);

        minx=min(xx,minx);

        maxy=max(yy,maxy);

        miny=min(yy,miny);

    }

    return max(maxx-minx,maxy-miny);

}

int main(){

    int t,i;

    double l,r,mid,mmid,ans;

    cin>>t;

    while(t--){

        cin>>n;

        for(i=0;i<n;i++)

            cin>>x[i]>>y[i];

        l=0.0;

        r=pi;

        while(r-l>1e-8){

            mid=(l+r)/2;

            mmid=(mid+r)/2;

            ans=cal(mid);

            if(ans<=cal(mmid)) r=mmid;

            else l=mid;

        }

        printf("%.2lf\n",ans*ans);

    }

    return 0;

}
View Code

 

 

 

你可能感兴趣的:(poj)