[计算几何]2018多校 B Pizza Hub

https://codeforces.com/gym/102192/problem/B

给一个三角形三个点的坐标,一条宽为w,长度无限的纸带,问把三角形放在纸带上且边界不越界(可以重合)时最小的长,三角形可以旋转。(就是希望希望分配给这个三角形、恰好包含这个三角形的最小的纸带长度。

解释起来好别扭呀。

分析:因为我着急回去看声入人心以及打游戏,所以字写得有点草率,如果有看的人就凑合看吧咳咳

每种情况中各种杂七杂八的情况判断一下就好了,代码也不复杂。(私以为这个代码超方便的!咳咳不过我没有看过其他人的代码……

[计算几何]2018多校 B Pizza Hub_第1张图片

[计算几何]2018多校 B Pizza Hub_第2张图片

关于函数solve和solve1里涉及的角度,画了个图解释一下,x1是L1和上面这条横线交点的横坐标

[计算几何]2018多校 B Pizza Hub_第3张图片

#include
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair piir;
const int N = 205;
const db eps=1e-6;
const db pi=acos(-1);
int sign(db k){if(k>eps) return 1;if(k<-eps) return -1;return 0;}
int dcmp(db k1,db k2){return sign(k1-k2);}
struct Point{
    db x,y;
    Point operator - (const Point k)const{return (Point){x-k.x,y-k.y};}
    db abs2(){return x*x+y*y;}
    db abs(){return sqrt(x*x+y*y);}
    db dis(const Point k)const{return ((*this)-k).abs();}
    db dis2(const Point k)const{return ((*this)-k).abs2();}
    void input(){double xx,yy;scanf("%lf%lf",&xx,&yy);x=xx;y=yy;}
}A,B,C;
db cc(Point a,Point b,Point c){
    db ab=a.dis(b),ac=a.dis(c),bc=b.dis(c);
    db ab2=a.dis2(b),ac2=a.dis2(c),bc2=b.dis2(c);
    return (ab2+ac2-bc2)/2/ab/ac;
}
db w;
db solve1(db l1,db l2,db arc){//l1>w的情况,和纸带边缘一定有交点
    db x1=sqrt(l1*l1-w*w);//和纸带边缘的交点
    db turn=acos(w/l1);
    if(dcmp(turn+arc,pi/2)>0) return 1e18;
    db now=pi/2-turn-arc;
    db y=sin(now)*l2;
    if(dcmp(y,w)>0) return sqrt(l2*l2-w*w);
    if(dcmp(x1,cos(now)*l2)<0) x1=cos(now)*l2;
    return x1;
}
db solve(db l1,db l2,db arc){
    if(dcmp(arc,pi/2)>0) return 1e18;//arc大于90°,这个角顶在原点的话啥姿势都塞不下哇
    if(dcmp(l1,w)>=0){
        return solve1(l1,l2,arc);
    }else{
        if(dcmp(l2*cos(arc),w)>0) return sqrt(l2*l2-w*w);
        else{
            return sin(arc)*l2;
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        A.input();B.input();C.input();
        double ww;
        scanf("%lf",&ww);w=ww;
        db arcA=acos(cc(A,B,C));
        db arcB=acos(cc(B,A,C));
        db arcC=acos(cc(C,A,B));
        db ans=1e18;
        db tmp;
        tmp=solve(A.dis(B),A.dis(C),arcA);
        if(dcmp(ans,tmp)>=0) ans=tmp;
      //  cout<=0) ans=tmp;
       // cout<=0) ans=tmp;
       // cout<=0) ans=tmp;
       // cout<=0) ans=tmp;
       // cout<=0) ans=tmp;
       // cout<1e17) printf("impossible\n");
        else cout<

 

你可能感兴趣的:(计算几何)