P8730 [蓝桥杯 2020 国 ABC] 皮亚诺曲线距离

· · 题解

题意

两个点之间, 如果沿着皮亚诺曲线走, 距离是多少?

思路

考虑递归求解

我们把每个 n 阶的图看成九个 n-1 阶的图。

根据 n 阶的和 n-1 阶的 (x,y) 之间的关系来逐层降阶。

对于 k 阶皮亚诺曲线点 a(k,x,y) 的距离表示为

其中 $a(1,\frac{x}{p},\frac{y}{p})$ 表示 $1$ 阶皮亚诺曲线距离,$p=3^{k-1}$。 $(3^p)^2$ 表示将整个 $k$ 阶皮亚诺曲线划分为 $1$ 阶皮亚诺曲线,$1$ 单元格内的总数,即总距离。 $a(k-1,xx,yy)$ 表示 $k$ 阶 $(xx,yy)$ 映射到 $k-1$ 阶的坐标, 为不完整单元格在 $k-1$ 阶到 $(xx,yy)$ 的距离。其划分规则为 ```cpp if(x/p==1) yy=p-1-y; if(y/p==1) xx=p-1-x; ``` 接下来,我们可以递归写出代码。 ### 代码 ```cpp #include <iostream> using namespace std; long long pw[200],leng[3][3] = {{0, 1, 2}, {5, 4, 3}, {6, 7, 8}};//3的i次幂和1阶皮亚诺曲线的距离矩阵 long long len(long long p,long long &x,long long &y)//计算距离,变换x,y { long long ix=x/p,iy=y/p; x%=p; y%=p; if(ix == 1) y=p-1-y; if(iy == 1) x=p-1-x; return leng[ix][iy]; } long long a(long long k,long long x,long long y)//k阶皮亚诺曲线点(0, 0)到点(x, y)的距离 { if(k==1) return leng[x][y]; else return pw[k-1]*pw[k-1]*len(pw[k-1],x,y)+a(k-1,x,y); } int main() { long long k,xx,yy,xxx,yyy; cin>>k>>xx>>yy>>xxx>>yyy; if(k>=40)k=39;//k>40无效且爆long long pw[0]=1; for (int i=1;i<=39;i++) pw[i] = pw[i - 1] * 3; long long ans=a(k,xx,yy)-a(k,xxx,yyy); cout<<(ans>0?ans:-ans)<<endl;//特判 ans<0 return 0; } ```