HDU 6398 Pizza Hub(计算几何)

探讨如何通过旋转使一个给定顶点坐标的三角形完全放入指定宽度的矩形中,并求解矩形最小高度。分析了三角形与矩形的不同相对位置并提供了实现代码。

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

Description

给出二维平面三角形的三个顶点坐标,现在要将这个三角形经过任意旋转使得其可以放在一个宽为ww的矩形中,问该矩形的高度最小值

Input

第一行一整数T表示用例组数,每组用例输入七个整数x1,y1,x2,y2,x3,y3,wx1,y1,x2,y2,x3,y3,w分别表示三点坐标和矩形的宽

(1T50000,0x1,y1,x2,y2,x3,y310000,1w10000)(1≤T≤50000,0≤x1,y1,x2,y2,x3,y3≤10000,1≤w≤10000)

Output

如果无解则输出impossibleimpossible,否则输出矩形高的最小值

Sample Input

2
0 0 3 0 0 4 10
0 0 3 0 0 4 1

Sample Output

2.400000000
impossible

Solution

简单分析可知三角形必然可以有一个顶点与该长方形底边一角重合,假设AA点与底角重合,那么有三种情况:

1.三角形一边在底部

2.B点在边上

3.CC点在边上

三种情况均有另一个点不在矩形区域的不合法状态,枚举三个点的顺序以及这三种情况更新答案即可

Code

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define eps 1e-9
#define INF 1e9
double x[3],y[3],w,ans;
int T;
int sgn(double x)
{
    if(fabs(x)<eps)return 0;
    if(x>=eps)return 1;
    return -1;
}
double get_a(double a,double b,double c)
{
    return acos((a*a+b*b-c*c)/(2.0*a*b));
}
double get_s(double a,double b,double c)
{
    double s=0.5*(a+b+c);
    return sqrt(s*(s-a)*(s-b)*(s-c));
}
double get_d(int i,int j)
{
    return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
void Solve(double ab,double ac,double bc)
{
    double A=get_a(ab,ac,bc);
    if(sgn(ab*sin(A)-w)>0||sgn(A-0.5*PI)>0)return ;
    if(sgn(w-max(ab,ac*cos(A)))>=0)
    {
        ans=min(ans,ac*sin(A));
        return ;
    }
    if(sgn(ab-w)>=0)
    {
        double a=acos(w/ab);
        if(sgn(w-ac*cos(a+A))>=0&&sgn(0.5*PI-a-A)>=0)
            ans=min(ans,max(ac*sin(a+A),sqrt(ab*ab-w*w)));
    }
    if(sgn(ac*cos(A)-w)>=0)
    {
        double a=acos(w/ac);
        if(sgn(a-A)>=0&&sgn(w-ab*cos(a-A))>=0)
            ans=min(ans,sqrt(ac*ac-w*w));
    }
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        for(int i=0;i<3;i++)scanf("%lf%lf",&x[i],&y[i]);
        scanf("%lf",&w);
        double d[3];
        d[0]=get_d(0,1),d[1]=get_d(0,2),d[2]=get_d(1,2);
        ans=INF;
        int a[3]={0,1,2};
        do
        {
            Solve(d[a[0]],d[a[1]],d[a[2]]);
        }while(next_permutation(a,a+3));
        if(sgn(ans-INF)==0)printf("impossible\n");
        else printf("%.9f\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值