POJ 3301 Texas Trip(三分枚举)

本文详细解析 POJ 3301 题目,通过坐标旋转角度变换公式,采用三分法求解最优解。通过实例学习逆向思维和几何算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://poj.org/problem?id=3301

这个题目刚拿到就向计算几何那里去想,后来又想到二分,想到三分,想了好长时间也没能得出一个有效的结论

后来看了题解明白了意思

这个题目的三分方法比较经典,题目默认正方形的一条边平行X轴,然后让点去旋转,三分枚举点旋转的角度

得出结果,这个题目的逆向思维值得学习。

这是坐标旋转的角度变换公式:

x1=cos(angle)*x-sin(angle)*y;

y1=sin(angle)*x+cos(angle)*y;

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <cmath>
using namespace std;
#define maxn 100
#define inf 1e12
#define eps 1e-8
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
#define PI acos(-1.0)
struct point{
    double x,y;
    point(double _x=0,double _y=0):x(_x),y(_y){}
}po[maxn];
int n;
double find_ans(double angle){
    double a=-inf,b=inf,c=-inf,d=inf,x,y;
    for(int i=0;i<n;i++){
        x=cos(angle)*po[i].x-sin(angle)*po[i].y;
        y=sin(angle)*po[i].x+cos(angle)*po[i].y;
        a=MAX(x,a);
        b=MIN(x,b);
        c=MAX(y,c);
        d=MIN(y,d);
    }
    return MAX(a-b,c-d);
}
double solve(){
    double ans=inf,l=0,r=PI,mid,now,temp;
    while(fabs(r-l)>eps){
        mid=(l+r)/2;
        temp=find_ans(mid);
        mid+=eps;
        now=find_ans(mid);
        mid-=eps;
        if(now > temp) r=mid;
        else l=mid;
        if(ans > temp)
        ans=temp;
    }
    return ans*ans;
}
int main(){
    int i,j,k,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(i=0;i<n;i++){
            scanf("%lf%lf",&po[i].x,&po[i].y);
        }
        printf("%.2lf\n",solve());
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值