19南昌网络赛L

校赛打杂没施展开。

题意:一开始给你一颗 (0,0)到(0,l)的树。

这棵树每一年会长出来三个幼芽(雾),长度均为l/4,方向分别是左转60,右转60,和不变。

年份<=14

考虑3^14直接暴力存边然后考虑每条边贡献。发现奇难无比。

考虑剪枝。

注意到如果一根树枝的被砍掉了那么他所有的孩子全都不算贡献了。妙啊!变成傻逼题。

抄一下板子。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef double db;
 4 const db eps=1e-6;
 5 const db pi=acos(-1);
 6 int sign(db k){
 7     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
 8 }
 9 int cmp(db k1,db k2){return sign(k1-k2);}
10 int inmid(db k1,db k2,db k3){return sign(k1-k3)*sign(k2-k3)<=0;}// k3 在 [k1,k2] 内
11 struct point{
12     db x,y;
13     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
14     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
15     point operator * (db k1) const{return (point){x*k1,y*k1};}
16     point operator / (db k1) const{return (point){x/k1,y/k1};}
17     int operator == (const point &k1) const{return cmp(x,k1.x)==0&&cmp(y,k1.y)==0;}
18     // 逆时针旋转
19     point turn(db k1){return (point){x*cos(k1)-y*sin(k1),x*sin(k1)+y*cos(k1)};}
20     bool operator < (const point k1) const{
21         int a=cmp(x,k1.x);
22         if (a==-1) return 1; else if (a==1) return 0; else return cmp(y,k1.y)==-1;
23     }
24     db abs(){return sqrt(x*x+y*y);}
25     db dis(point k1){return ((*this)-k1).abs();}
26 };
27 db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
28 db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
29 point getLL(point k1,point k2,point k3,point k4){
30     db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3); return (k1*w2+k2*w1)/(w1+w2);
31 }
32 struct line{
33     point p[2];
34     line(point k1,point k2){p[0]=k1; p[1]=k2;}
35     point& operator [] (int k){return p[k];}
36     point dir(){return p[1]-p[0];}
37 };
38 int check(line a,line b){//线段与直线
39     if(cross(a[0]-b[0],a[0]-b[1])*cross(a[1]-b[0],a[1]-b[1])>0 ) return 1;
40     return 0;
41 }
42 int t,n;db l,x,y,k;line cut = {{0,0},{0,0}};
43 vector<line> v;
44 db dfs(line now,int stp){
45     db ans = 0;
46     if(stp==n)return ans;
47     if(check(now,cut)) {
48         ans+=now.dir().abs();
49         ans+=dfs({now[1], now[1] + now.dir() / 4}, stp + 1);//原方向
50         ans+=dfs({now[1], now[1] + now.dir().turn(pi/3) / 4}, stp + 1);//逆时针60
51         ans+=dfs({now[1], now[1] + now.dir().turn(-pi/3) / 4}, stp + 1);//顺时针60
52     }else{//砍了
53         point xx = getLL(now[0],now[1],cut[0],cut[1]);
54         ans+=now[0].dis(xx);
55     }
56     return ans;
57 }
58 int main(){
59 //    printf("%.11f\n",pow(3,15));
60 //    printf("%.11f\n",sin(90));
61     scanf("%d",&t);
62     while (t--){
63         v.clear();
64         scanf("%lf%d%lf%lf%lf",&l,&n,&x,&y,&k);
65         line o={{0,0},{0,l}};
66         cut = {{x,y},{x+10000,y+k*10000}};
67         db ans = dfs(o,0);
68         printf("%.6f\n",ans);
69     }
70 }
71 /**
72 1
73 16 2 0 18 0
74  */
View Code

猜你喜欢

转载自www.cnblogs.com/MXang/p/10743654.html