2019南昌邀请赛 L 计算几何 G(待补)

时间:2019-04-20
本文章向大家介绍2019南昌邀请赛 L 计算几何 G(待补),主要包括2019南昌邀请赛 L 计算几何 G(待补)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
#include<bits/stdc++.h>
const double PI=acos(-1.0);
const double TT=PI/3;
using namespace std;
struct Point  { double x,y; Point(){} Point(double x, double y) :x(x), y(y){}  };;
struct Segment{ Point a,b;  Segment(Point x,Point y )     { a=x;b=y; };  Segment(){}; };;
struct Line   { Point a,b;  Line(Point x,Point y )        { a=x;b=y; };  Line(){}; };;
typedef Point Point;
Point operator + (Point A, Point B){ return Point(A.x+B.x, A.y+B.y); } // 向量相加
Point operator - (Point  A, Point  B){ return Point(B.x-A.x, B.y-A.y); } // 向量生成   A-B;
double operator * (Point A, Point B){ return A.x*B.x-A.y*B.y;          } // 点积
double operator ^ (Point A, Point B){ return A.x*B.y-A.y*B.x;          } // 叉积
double Dot(Point A, Point B)   { return A.x*B.x + A.y*B.y; }  // 点积
double Cross(Point A, Point B) { return A.x*B.y-A.y*B.x;   }  // 叉积
double Length(Point A)          { return sqrt(Dot(A, A));   } // 向量长度
double dis(Point a,Point b)      { return sqrt( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) ); }
Line qq;
bool check(Segment A,Line B)
{
    Point a=A.a; Point b=A.b;
    Point c=B.a; Point d=B.b;
    if(Cross(a-c,a-d)*Cross(b-c,b-d)>0 ) return 1;
    else return 0;
    return 0;
}
Point make(Segment A,Line B)
{
    Point a=A.a; Point b=A.b;Point c=B.a; Point d=B.b;
    double A1=b.y-a.y,B1=-(b.x-a.x),C1=b.y*a.x-b.x*a.y;
    double A2=d.y-c.y,B2=-(d.x-c.x),C2=d.y*c.x-d.x*c.y;
    double k=A1*B2-A2*B1;
    double x=-(B1*C2-C1*B2)*1.000000000/k;
    double y=(A1*C2-C1*A2)*1.00000000/k;
    Point kk; kk.x=x; kk.y=y;  return kk;
}
double dfs(double l,int k,int d,Point x,double ff)
{
    if(k==d) return 0;
    double ans=0;
    Segment x1;
    x1.a=x;
    x1.b.x=x.x+l*sin(ff); x1.b.y=x.y+l*cos(ff);
    Point W;
    W.x=x.x+l*sin(ff); W.y=x.y+l*cos(ff);
    if(check(x1,qq)==1)
    {
        ans+=l;
        ans+=dfs(l/4,k+1,d,W,ff-TT);
        ans+=dfs(l/4,k+1,d,W,ff);
        ans+=dfs(l/4,k+1,d,W,ff+TT);
    }
    else
    {
        Point P=make(x1,qq); ans+=dis(x,P);
    }
    return ans;
}
void work(double l,int d)
{
    Segment x1;
    x1.a.x=0; x1.a.y=0;
    x1.b.x=0; x1.b.y=l;
    double ans=0;
    Point W;  W.x=0;  W.y=l;
    if(check(x1,qq)==1)
    {
        ans+=l;
        ans+=dfs(l/4,1,d,W,-TT);
        ans+=dfs(l/4,1,d,W,0);
        ans+=dfs(l/4,1,d,W,TT);
    }
    else
    {
        Point x;
        x.x=0;
        x.y=0;
        Point P=make(x1,qq); ans+=dis(x,P);
    }
    cout<<ans<<endl;
}
int main()
{
    cout<<fixed<<setprecision(6);
    int T; cin>>T;
    while(T--)
    {
        int d;
        double l,x1,y1,k; cin>>l>>d>>x1>>y1>>k;
        qq.a.x=x1; qq.a.y=y1;
        qq.b.x=x1+1; qq.b.y=y1+k*1;
        work(l,d);
    }
}