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
",ans*ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3234215.html