【计算几何】2019牛客暑期多校训练营(第五场) - I - three points 1

题目链接https://ac.nowcoder.com/acm/contest/885/I


题意

给出一个x坐标和y坐标的范围,给出三条边长,问三角形的三点坐标(或者是一条线)


题解

一个点固定,另一个点靠边,计算第三个点。注意最后的输出三点是有顺序的
计算几何好烦啊


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const ll N=2e5+7;
const db eps=1e-7;
const db pi=acos(-1);
int sign(db k){
    if (k>eps) return 1; else if (k<-eps) return -1; return 0;
}
int cmp(db k1,db k2){return sign(k1-k2);}
struct point{
    db x,y;
    point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
    point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    point operator * (db k1) const{return (point){x*k1,y*k1};}
    point operator / (db k1) const{return (point){x/k1,y/k1};}
    int operator == (const point &k1) const{return cmp(x,k1.x)==0&&cmp(y,k1.y)==0;}
    db abs(){return sqrt(x*x+y*y);} //向量长度
    db abs2(){return x*x+y*y;}
    db dis(point k1){return ((*this)-k1).abs();} //两点距离
    point turn(db k1){return (point){x*cos(k1)-y*sin(k1),x*sin(k1)+y*cos(k1)};}
    void print(){printf("%.11f %.11f",x,y);} //输出
};
db w,h;
point getC(point A,point B,db a,db b,db c,int sz){
    db cs=(b*b+c*c-a*a)/2/b/c;
    point AB=B-A;
    point AC=AB.turn(sz*acos(cs))*b/c;
    return AC+A;
}
point getBx(point A,db x){
    if(cmp(x,w)<=0) return (point){x,0};
    return (point){w,sqrt(x*x-w*w)};
}
point getBy(point A,db y){
    if(cmp(y,h)<=0) return (point){0,y};
    return (point){sqrt(y*y-h*h),h};
}
db a,b,c;
bool ck(point A,point B,point C){
    if(cmp(B.x,w)>0||cmp(B.x,0)<0||cmp(B.y,h)>0||cmp(B.y,0)<0) return false;
    if(cmp(C.x,w)>0||cmp(C.x,0)<0||cmp(C.y,h)>0||cmp(C.y,0)<0) return false;

    if(cmp(A.dis(B),a)==0&&cmp(A.dis(C),b)==0){
        A.print();printf(" ");B.print();printf(" ");C.print();printf("\n");
        return true;
    }

    if(cmp(A.dis(C),a)==0&&cmp(A.dis(B),b)==0){
        A.print();printf(" ");C.print();printf(" ");B.print();printf("\n");
        return true;
    }

    if(cmp(B.dis(A),a)==0&&cmp(B.dis(C),b)==0){
        B.print();printf(" ");A.print();printf(" ");C.print();printf("\n");
        return true;
    }

    if(cmp(B.dis(C),a)==0&&cmp(B.dis(A),b)==0){
        B.print();printf(" ");C.print();printf(" ");A.print();printf("\n");
        return true;
    }

    if(cmp(C.dis(A),a)==0&&cmp(C.dis(B),b)==0){
        C.print();printf(" ");A.print();printf(" ");B.print();printf("\n");
        return true;
    }

    if(cmp(C.dis(B),a)==0&&cmp(C.dis(A),b)==0){
        C.print();printf(" ");B.print();printf(" ");A.print();printf("\n");
        return true;
    }

}
int main() {
    int t;

    scanf("%d",&t);
    while(t--){
        scanf("%lf%lf%lf%lf%lf",&w,&h,&a,&b,&c);
        point A,B,C;

        A=(point){0,0};B=getBx(A,a);C=getC(A,B,b,c,a,1);
        if(ck(A,B,C)) continue;
        A=(point){0,0};B=getBx(A,a);C=getC(A,B,c,b,a,1);
        if(ck(A,B,C)) continue;

        A=(point){0,0};B=getBx(A,b);C=getC(A,B,a,c,b,1);
        if(ck(A,B,C)) continue;
        A=(point){0,0};B=getBx(A,b);C=getC(A,B,c,a,b,1);
        if(ck(A,B,C)) continue;

        A=(point){0,0};B=getBx(A,c);C=getC(A,B,a,b,c,1);
        if(ck(A,B,C)) continue;
        A=(point){0,0};B=getBx(A,c);C=getC(A,B,b,a,c,1);
        if(ck(A,B,C)) continue;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值