题目大意:
给一条折线,每一次操作把这条折线的所有线段变换成跟这条折线的相同形状,重复d次。问此时从头到尾走全长的f(0≤f≤1)倍,将停在哪个点上。
解题思路:
假设做了一次分形后得到折线长度是原来的
k
倍,则深度为d的分形(操作了d-1次)的长度是原来的
要注意每次变换后图形需要旋转和缩放,所以要预处理出每条线段的偏转角度。
ps:这道题卡精度卡到爆炸,double运算能少就少。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=105;
const double eps=1e-8;
struct point
{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
inline friend point operator - (const point &a,const point &b)
{return point(a.x-b.x,a.y-b.y);}
inline friend point operator + (const point &a,const point &b)
{return point(a.x+b.x,a.y+b.y);}
inline friend point operator / (const point &a,const double &b)
{return point(a.x/b,a.y/b);}
inline friend point operator * (const point &a,const double &b)
{return point(a.x*b,a.y*b);}
inline friend double operator * (const point &a,const point &b)
{return a.x*b.y-a.y*b.x;}
inline double dis(){return sqrt(x*x+y*y);}
}p[N];
struct line
{
point v;
double len,ang,ratio;
line(){}
line(point st,point ed)
{len=(ed-st).dis();v=ed-st;}
}l[N];
int T,n,d;
double k,f,rate,L;
double calc(point a,point b)
{
return acos((a.x*b.x+a.y*b.y)/(a.dis()*b.dis()))*(a*b>0?1:-1);
}
point rotate(point a,double theta)
{
return point(a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta));
}
void go(point s,double R,int dep,double theta,double ratio)
{
for(int i=1;i<n;i++)
{
double len=l[i].len*ratio*R;
if(L-len<eps)
{
if(dep)go(s,R/rate,--dep,theta+l[i].ang,ratio*l[i].ratio);
else
{
s=s+rotate(l[i].v,theta)/l[i].len*L;
printf("(%.10f,%.10f)\n",s.x,s.y);
}
return;
}
else L-=len,s=s+rotate(l[i].v,theta)*ratio;
}
}
int main()
{
//freopen("lx.in","r",stdin);
//freopen("lx.out","w",stdout);
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
scanf("%d%lf",&d,&f);d--;
k=0;
for(int i=1;i<n;i++)
{
k+=(p[i+1]-p[i]).dis();
l[i]=line(p[i],p[i+1]);
l[i].ratio=l[i].len/(p[n]-p[1]).dis();
l[i].ang=calc(p[n]-p[1],p[i+1]-p[i]);
}
rate=k/(p[n]-p[1]).dis();
double R=1;
for(int i=1;i<=d;i++)R*=rate;
L=f*R*k;
go(p[1],R,d,0,1);
}
return 0;
}