传送门:poj3845
题解
设 t = 折 线 总 长 起 点 到 终 点 的 直 线 距 离 t=\frac{折线总长}{起点到终点的直线距离} t=起点到终点的直线距离折线总长。
一条线段迭代 d d d次后的长度就是原来的 t d t^d td倍。
考虑从 d − 1 d-1 d−1逐层确定目标点所在的线段,迭代查找,需要记录坐标的放缩和旋转角度。
很卡精度!计算角的大小函数 cal() \text{cal()} cal()里面就把 / ( 2 ∗ A ∗ B ) /(2*A*B) /(2∗A∗B)写成了 / 2 / A / B /2/A/B /2/A/B,精度就被卡了!
代码
#include<cstdio>
#include<cmath>
#include<algorithm>
#define sqr(x) (x*x)
typedef double db;
using namespace std;
const db eps=1e-8;
const int N=110;
int tk,n,d;
db t,sum,f,res,rat,xz,bs;
struct P{
db x,y;
P(db x_=0.0,db y_=0.0):x(x_),y(y_){};
inline P operator +(const P&ky){return P(x+ky.x,y+ky.y);}
inline P operator -(const P&ky){return P(x-ky.x,y-ky.y);}
inline db operator ^(const P&ky){return x*ky.y-y*ky.x;}
inline P operator *(const db&ky){return P(x*ky,y*ky);}
inline P operator /(const db&ky){return P(x/ky,y/ky);}
inline db sq(){return sqrt(x*x+y*y);}
bool operator <(const P&ky)const{
db a=atan2(y,x),b=atan2(ky.y,ky.x);
return a!=b?a<b:x<ky.x;
}
}p[N],st;
inline db dist(P a,P b){return (a-b).sq();}
struct Line{
P dir;db len,ag,rat;
Line(){};
Line(P st,P ed){dir=ed-st;len=dist(st,ed);}
}l[N];
inline int dcmp(db x){if(fabs(x)<eps) return 0;return x>0?1:-1;}
inline bool onlf(P a,P b,P c){return (dcmp((c-b)^(b-a))>-1);}
inline db cal(P a,P b){
db A=a.sq(),B=b.sq();P c=b-a;
return acos((a.x*a.x+a.y*a.y+b.x*b.x+b.y*b.y-c.x*c.x-c.y*c.y)/(A*B*2))*((a^b)>0?1:-1);
}
inline P rot(P a,db b)
{return P(a.x*cos(b)-a.y*sin(b),a.x*sin(b)+a.y*cos(b));}
int main(){
int i;db len;
for(scanf("%d",&tk);tk;--tk){
sum=0.0;scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
for(bs=dist(p[1],p[n]),i=1;i<n;++i){
l[i]=Line(p[i],p[i+1]);sum+=l[i].len;
l[i].rat=l[i].len/bs;l[i].ag=cal(p[n]-p[1],p[i+1]-p[i]);
}
t=sum/bs;scanf("%d%lf",&d,&f);d--;
for(bs=1.0,i=1;i<=d;++i) bs*=t;
res=sum*bs*f;st=p[1];rat=1.0;xz=0;
for(;d>=0;--d){
for(i=1;i<n;++i){
len=l[i].len*rat*bs;
if(res-len<eps) break;res-=len;
st=st+(rot(l[i].dir,xz)*rat);
}
if(!d){
st=st+(rot(l[i].dir,xz)/l[i].len*res);
printf("(%.10f,%.10f)\n",st.x,st.y);
}
bs/=t;xz+=l[i].ag;rat*=l[i].rat;
}
}
return 0;
}