题意:

给一个三角形,放在一个给定宽度的无线长的矩形中,要求占得长度最小。

题解:

分两种情况,一是三角形的边与矩形的边重合,二是三角形的两个点卡在矩形的两条边上。

对于第一种情况,枚举底边,算出第三点在底边的投影,就知道要占据的最小宽度,若小于等于矩形宽度,再算出占据的高度。

对于第二种情况,枚举卡在矩形的两条边上的两个点,算出该边与矩形宽度的夹角,第三点若在矩形内,再算出占据的高度。

 

代码:

#include<bits/stdc++.h>
#define N 100010
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define cl clear
#define si size
#define lb lowwer_bound
#define eps 1e-8
#define mem(x) memset(x,0,sizeof x)
#define sc(x) scanf("%d",&x)
#define pi 3.141592653589793
using namespace std;
int dcmp(double x){if (fabs(x)<eps)return 0;else return x<0?-1:1;}
struct Point
{
    double  x,y;
    Point(double x=0,double y=0):x(x),y(y){ }
};

Point a[3]; double d,ans; int fg;

typedef Point Vector;
Vector operator + (Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}  //点积
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} //叉积
double Length(Vector a){return sqrt(Dot(a,a));}
Vector operator * (Vector a,double b){return Vector(a.x*b,a.y*b);}
double Angle(Vector a,Vector b){return acos(Dot(a,b)/Length(a)/Length(b));}// 范围[0,180]

//点到直线ab的投影
Point GetLineProjection(Point p,Point a,Point b)
{
    Vector v=b-a;
    return a+v*(Dot(v,p-a)/Dot(v,v));
}

double Max(Point i,Point j,Point k)
{
return max(Length(i-j),max(Length(i-k),Length(j-k)));
}

void check(int i,int j,int k)
{
    Point v=GetLineProjection(a[k],a[i],a[j]);
    if (dcmp(Max(v,a[i],a[j])-d)<=0) fg=1,ans=min(ans,Length(v-a[k]));
}
//极角,范围[0,360)
double JJ(Vector a)
{
    double x=atan2(a.y,a.x);
    if (a.y<0)x+=pi*2;
    return x;
}
Vector Rotate(Vector a,double rad)// 向量 a 逆时针旋转 rad
{return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));}

void checkk(int i,int j,Point k)
{
    double l=Length(a[i]-a[j]);
    double ang=acos(min(d/l,1.0));
    if (Cross(k-a[i],a[j]-a[i])>0) swap(i,j);
    if (dcmp(Angle(k-a[i],a[j]-a[i])+ang-pi*0.5)<=0 &&
        dcmp(Angle(k-a[j],a[i]-a[j])-ang-pi*0.5)<=0)
        {
            fg=1;
            Point v1=a[j]-a[i],v2=k-a[i];
            double aa=JJ(v1)-pi*2;
            v2=Rotate(v2,ang-aa);
            v1=Rotate(v1,ang-aa);
            double  t1=max(0.0,max(v1.y,v2.y)),
                    t2=min(0.0,min(v1.y,v2.y));
            ans=min(ans,t1-t2);
        }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        for (int i=0;i<3;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
        scanf("%lf",&d);
        fg=0; ans=1e9;

        for (int i=0;i<3;i++) check(i,(i+1)%3,(i+2)%3);

        for (int i=0;i<3;i++)
        {
            checkk(i,(i+1)%3,a[(i+2)%3]);
            Point v=GetLineProjection(a[(i+2)%3],a[i],a[(i+1)%3]);
            checkk(i,(i+1)%3,v*2-a[(i+2)%3]);
        }
        if (fg) printf("%.8f\n", ans );else puts("impossible");
    }
}