目录:
题目:
分析:
把第n级分形图看成是一个二维坐标,我们需要求出两个点的坐标,然后,根据两点间的距离公式求结果
首先这是一个分形图肯定需要用到递归思想
我们分别比较第n-1级分形图在第n级分形图中的位置来进行计算第n级分形图的情况(n是级数,s是需要求的编号)
下面就讲下关于递归的一些东西:
当n等于1时(即是最初的那个第1级分形图)
1.当s等于1,
x=1,y=1
x
=
1
,
y
=
1
2.当s等于2,
x=1,y=2
x
=
1
,
y
=
2
3.当s等于3,
x=2,y=2
x
=
2
,
y
=
2
4.当s等于4,
x=2,y=1
x
=
2
,
y
=
1
而当我们在递归时的式子,则是分成四种情况:
1.当前编号小于上一级编号总数时
该情况说明当前编号是在n级分形图的左上角,
但是左上角分形图是
n−1
n
−
1
级分形图逆时针旋转90度得到的
所以我们带入递归式时,需要将x和y,倒一下
不明白的同学可以这样看:
第1级道路:
(1,1)−>(1,2)−>(2,2)−>(2,1)
(
1
,
1
)
−
>
(
1
,
2
)
−
>
(
2
,
2
)
−
>
(
2
,
1
)
第2级道路左上角:
(1,1)−>(2,1)−>(2,2)−>(1,2)
(
1
,
1
)
−
>
(
2
,
1
)
−
>
(
2
,
2
)
−
>
(
1
,
2
)
两种情况的x和y情况互换了
递归式:
find(n−1,s,y,x)
f
i
n
d
(
n
−
1
,
s
,
y
,
x
)
2.当编号小于2倍的
n−1
n
−
1
数目时,说明当前编号s在分形图的右上角
由于右边的分形图没有经过旋转
所以我们直接带入递归式,
需要注意的是我们的编号要减去上一级的编号,
因为我们始终是根据上一级来推出下一级
递归式:
find(n−1,s−p[n−1],x,y)
f
i
n
d
(
n
−
1
,
s
−
p
[
n
−
1
]
,
x
,
y
)
递归出来之后,我们的x需要加上上一级的边的大小
这从分形图中很容易看出
即
x=x+(1<<n−1)
x
=
x
+
(
1
<<
n
−
1
)
3.当编号小于3倍的
n−1
n
−
1
数目时,跟第2种情况类似,
只是递归出来之后,x和y都需要加上上一级的边的大小
即
find(n−1,s−2∗p[n−1],x,y)
f
i
n
d
(
n
−
1
,
s
−
2
∗
p
[
n
−
1
]
,
x
,
y
)
//注意编号必须要小于上一级的大小
// 因为我们是放在上一级的情况下考虑的
x+=(1<<n−1)
x
+
=
(
1
<<
n
−
1
)
y+=(1<<n−1)
y
+
=
(
1
<<
n
−
1
)
4.最后一种情况,s在第n级分形图的左下角
这种情况跟第2种情况差不多,
我们先按照逆时针的情况来解决,这就跟第1种情况一样了
然后比较坐标x和y的关系,
容易看出,顺时针相比于逆时针
x为
(1<<n)+1−x
(
1
<<
n
)
+
1
−
x
y为
(1<<(n−1))+1−y
(
1
<<
(
n
−
1
)
)
+
1
−
y
代码:
#pragma GCC optimize("3")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
LL p[16];
LL n=read();
void find(LL n,LL s,LL &x,LL &y)
{
if(n==1)
{
if(s==1) x=1,y=1;
else if(s==2) x=1,y=2;
else if(s==3) x=2,y=2;
else x=2,y=1;
return;
}
if(s<=p[n-1])
find(n-1,s,y,x);
else if(s<=2*p[n-1])
{
find(n-1,s-p[n-1],x,y);
y+=(1<<n-1);
}
else if(s<=3*p[n-1])
{
find(n-1,s-2*p[n-1],x,y);
x+=(1<<n-1);
y+=(1<<n-1);
}
else
{
find(n-1,s-3*p[n-1],y,x);
x=(1<<n)+1-x;
y=(1<<n-1)+1-y;
}
return;
}
int main()
{
LL bx,by,cx,cy;
p[1]=4;
for(int i=2;i<=15;i++) p[i]=p[i-1]*4;
while(n>0)
{
LL a=read(),b=read(),c=read();
find(a,b,bx,by);
find(a,c,cx,cy);
printf("%.0f\n",sqrt((bx-cx)*(bx-cx)+(by-cy)*(by-cy))*10);
n--;
}
return 0;
}