UVALive - 8295(几何)

看的蓝书的板子,Line不知道什么意思,卡了一个小时,最后在前面找到了p是点,v是向量,写了整场比赛,思路就是求出所有的点,然后求距离

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
struct Point
{
    double x,y;
    Point(double xx=0,double yy=0):x(xx),y(yy) {}
};
typedef Point Vector;
const double eps=1e-6;
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);
}
Vector operator *(Vector A,double p)
{
    return Vector(A.x*p,A.y*p);
}
Vector operator /(Vector A,double p)
{
    return Vector(A.x/p,A.y/p);
}
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
bool operator == (const Point &a,const Point &b)
{
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Vector A,Vector B)
{
    return A.x*B.x+A.y*B.y;
}
double Length(Vector A)
{
    return sqrt(Dot(A,A));
}
double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}
double distoline(Point P,Point A,Point B)
{
    Vector v1=B-A,v2=P-A;
    return fabs(Cross(v1,v2))/Length(v1);
}
struct Circle
{
    Point c;
    double r;
    Circle(Point c,double r):c(c),r(r) {}
    Point point(double a)
    {
       return Point(c.x+cos(a)*r,c.y+sin(a)*r);
    }
};
struct Line
{
    Point v,p;
    Line(Point v,Point p):v(v),p(p) {}
    Point point(double t)
    {
        Point zz=p+v*t;
        return zz;
    }
};
Circle circleout(Point p1,Point p2,Point p3)
{
    double Bx=p2.x-p1.x,By=p2.y-p1.y;
    double Cx=p3.x-p1.x,Cy=p3.y-p1.y;
    double D=2*(Bx*Cy-By*Cx);
    double cx=(Cy*(Bx*Bx+By*By) - By*(Cx*Cx+Cy*Cy))/D+p1.x;
    double cy=(Bx*(Cx*Cx+Cy*Cy) - Cx*(Bx*Bx+By*By))/D+p1.y;
    Point p=Point(cx,cy);
    return Circle(p,Length(p1-p));
}
Circle circleint(Point p1,Point p2,Point p3)
{
    double a=Length(p2-p3);
    double b=Length(p3-p1);
    double c=Length(p1-p2);
    Point p=(p1*a+p2*b+p3*c)/(a+b+c);
    return Circle(p,distoline(p,p1,p2));
}
int getlinejiaocircle(Line L,Circle C,double &t1,double &t2,vector<Point> &sol)
{
    double a=L.v.x,    b=L.p.x-C.c.x,   c=L.v.y,   d=L.p.y-C.c.y;
    double e=a*a+c*c,   f=2*(a*b+c*d),   g=b*b+d*d-C.r*C.r;
    double delta=f*f-4*e*g;
    if(dcmp(delta)<0) return 0;
    if(dcmp(delta)==0)
    {
        t1=t2=-f/(2*e);
        sol.push_back(L.point(t1));
        return 1;
    }

    t1=(-f-sqrt(delta))/(2*e); sol.push_back(L.point(t1));
    t2=(-f+sqrt(delta))/(2*e); sol.push_back(L.point(t2));
    return 2;
}
Point gettwolinejiao(Point P,Vector v,Point Q,Vector w)
{
    Vector u=P-Q;
    double t=Cross(w,u)/Cross(v,w);
    return P+v*t;
}
int t;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        int Case;
        scanf("%d",&Case);
        double bx,cx,cy;
        scanf("%lf%lf%lf",&bx,&cx,&cy);
        Point A=Point(0,0),B=Point(bx,0),C=Point(cx,cy);
        Circle I=circleint(A,B,C);
        Circle O=circleout(A,B,C);
        double t1=0,t2=0;
        vector<Point> sol;
        Point ii=I.c;
        sol.clear();
        Line bi=Line(ii-B,B);
        int nn=getlinejiaocircle(bi,O,t1,t2,sol);
        Point N;
        if(sol[0]==B) N=sol[1];
        else N=sol[0];


        sol.clear();
        Line ai=Line(ii-A,A);
        nn=getlinejiaocircle(ai,O,t1,t2,sol);
        Point M;
        if(sol[0]==A) M=sol[1];
        else M=sol[0];


        sol.clear();
        Line ci=Line(ii-C,C);
        nn=getlinejiaocircle(ci,O,t1,t2,sol);
        Point P;
        if(sol[0]==C) P=sol[1];
        else P=sol[0];

        Vector AC=C-A;
        Vector NP=P-N;
        Point F=gettwolinejiao(A,AC,N,NP);
        Vector AB=B-A;
        Point E=gettwolinejiao(A,AB,N,NP);
        double ef=Length(E-F);

        Vector NM=M-N;
        Point G=gettwolinejiao(A,AC,N,NM);
        double fg=Length(G-F);

        Vector PM=M-P;
        Point K=gettwolinejiao(A,AB,P,PM);
        double ek=Length(E-K);

        Vector BC=C-B;
        Point J=gettwolinejiao(B,BC,P,PM);
        double kj=Length(J-K);

        Point H=gettwolinejiao(N,NM,B,BC);
        double gh=Length(H-G);
        double hj=Length(J-H);

        double ans=ef+fg+ek+kj+gh+hj;
        printf("%d ",Case);
        printf("%.4f ",ef);
        printf("%.4f ",fg);
        printf("%.4f ",gh);
        printf("%.4f ",hj);
        printf("%.4f ",kj);
        printf("%.4f\n",ek);
    }
    return 0;
}

 

posted on 2018-08-19 21:22  发牌员  阅读(148)  评论(0)    收藏  举报

导航