Fractal Streets
[by_041]
题目理解
-
本题是和希尔伯特曲线有关的一道规律题(因为存在重复单元)
-
原来的基础方向是这样
]
的,我们可以将其划分为四个部分 ① ∣ ② ④ ∣ ③ \frac{①|②}{④|③} ④∣③①∣②,根据题意在②③部分中的细分单位结构和原来的整体方向相同,而在①处位置的细分方向沿主对角线方向翻转,④处沿右对角线翻转,所以有翻转状态st1,st2
表示的细分单位结构,见下表:
- 所以我们可以从二进制的高位 2 2 n − 1 2^{2n-1} 22n−1和 2 2 n − 1 2^{2n-1} 22n−1开始每俩位截取一次,用得到的状态更新细分结构的方向即位置,已 n = 2 n=2 n=2为例,可以看到二进制下房子编号的规律:
-
综上,我们可以得到本体的具体思路:
- 每两位地取二进制定位下一层细分结构位置
- 移动当前表示位置坐标的二进制数,生成相应的下层位置
- 按照规则翻转当前状态得到下一层的结构方向
-
还要注意数据大小需要用到
long long
和double
,输出格式一定要用printf
的%.0lf
关键格式,不然会WA(cout
宣布破产!)!!! -
AC代码如下:
#include<iostream>
#include<cmath>
using namespace std;
long long pow4[41];
void guai(long long n,long long s,long long &x,long long &y)
{
if(n==1)
{
if(s==1)
{
x=1;
y=1;
}
else
if(s==2)
{
x=1;
y=2;
}
else
if(s==4)
{
x=2;
y=1;
}
else
{
x=2;
y=2;
}
return;
}
if(s<=pow4[n-1])
{
guai(n-1,s,y,x);
}
else if(s<=2*pow4[n-1])
{
guai(n-1,s-pow4[n-1],x,y);
y+=(1<<(n-1));
}
else if(s<=3*pow4[n-1])
{
guai(n-1,s-2*pow4[n-1],x,y);
x+=(1<<(n-1));
y+=(1<<(n-1));
}
else
{
guai(n-1,s-3*pow4[n-1],y,x);
x=(1<<n)+1-x;
y=(1<<(n-1))+1-y;
}
}
int main()
{
pow4[1]=4;
for(int i=2;i<=33;i++)
{
pow4[i]=4*pow4[i-1];
}
int T;
scanf("%d",&T);
while(T--)
{
long long s,e,n,sx,sy,ex,ey;
scanf("%lld%lld%lld",&n,&s,&e);
guai(n,s,sx,sy);
guai(n,e,ex,ey);
printf("%.0f\n",sqrt(((double)sx-(double)ex)*((double)sx-(double)ex)+((double)sy-(double)ey)*((double)sy-(double)ey))*10);
}
return 0;
}
- 原来废掉但是思路正确的枚举情况の代码(可便于理解🤔and有纪念价值😜):
#include<stdio.h>
#include<iostream>
#include<bitset>
#include<cmath>
using namespace std;
// bitset<101>u,v;
bool st1,st2,u[1001],v[1001];
//st1表示主对角线上的翻转情况,st2表示副对角线上的翻转情况
long long n,val,ux,uy,vx,vy;
int main()
{
//cout<<(unsigned long long)(1.6+0.5)<<endl;
// freopen(".out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
cin>>n>>val;
val--;
// u=val;
// cout<<u<<endl;
// u=0;
int bs_f=0;
while(val)
{
u[bs_f++]=val%2;
val/=2;
}
// cout<<u;
cin>>val;
// v=val-1;
// cout<<u<<endl<<v<<endl;
st1=st2=false;
ux=uy=vx=vy=0;
long long nn=n;
while(n--)
{
// u[(n<<1)+1] u[n<<1] st1 st2
ux<<=1;
uy<<=1;
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==0&&st2==0)
{
st1=1;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==0&&st2==0)
{
uy++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==0&&st2==0)
{
uy++;
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==0&&st2==0)
{
ux++;
st2=1;
continue;
}
///
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==1&&st2==0)
{
st1=0;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==1&&st2==0)
{
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==1&&st2==0)
{
uy++;
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==1&&st2==0)
{
uy++;
st2=0;
continue;
}
///
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==0&&st2==1)
{
ux++;uy++;st1=1;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==0&&st2==1)
{
uy++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==0&&st2==1)
{
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==0&&st2==1)
{
ux++;st2=0;
continue;
}
///
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==1&&st2==1)
{
ux++;uy++;st1=0;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==1&&st2==1)
{
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==1&&st2==1)
{
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==1&&st2==1)
{
uy++;st2=0;
continue;
}
}
vx=ux;
vy=uy;
ux=uy=st1=st2=0;
// u=val-1;
val--;bs_f=0;
for(int iiii=0;iiii<=100;iiii++)
u[iiii]=0;
while(val)
{
u[bs_f++]=val%2;
val/=2;
}
n=nn;
while(n--)
{
// u[(n<<1)+1] u[n<<1] st1 st2
ux<<=1;
uy<<=1;
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==0&&st2==0)
{
st1=1;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==0&&st2==0)
{
uy++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==0&&st2==0)
{
uy++;
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==0&&st2==0)
{
ux++;
st2=1;
continue;
}
///
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==1&&st2==0)
{
st1=0;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==1&&st2==0)
{
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==1&&st2==0)
{
uy++;
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==1&&st2==0)
{
uy++;
st2=0;
continue;
}
///
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==0&&st2==1)
{
ux++;uy++;st1=1;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==0&&st2==1)
{
uy++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==0&&st2==1)
{
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==0&&st2==1)
{
ux++;st2=0;
continue;
}
///
if(u[(n<<1)+1]==0&&u[n<<1]==0&&st1==1&&st2==1)
{
ux++;uy++;st1=0;
continue;
}
if(u[(n<<1)+1]==0&&u[n<<1]==1&&st1==1&&st2==1)
{
ux++;
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==0&&st1==1&&st2==1)
{
continue;
}
if(u[(n<<1)+1]==1&&u[n<<1]==1&&st1==1&&st2==1)
{
uy++;st2=0;
continue;
}
}
// cout<<ux<<" "<<uy<<" - "<<vx<<" "<<vy<<endl;
long long a_x1=ux,a_y1=uy,a_x2=vx,a_y2=vy;
// cout<<(long long)(sqrt(((a_x1-a_x2)*(a_x1-a_x2)+(a_y1-a_y2)*(a_y1-a_y2)))*10+0.5)<<endl;
printf("%.0lf\n",(sqrt((((double)a_x1-(double)a_x2)*((double)a_x1-(double)a_x2)+((double)a_y1-(double)a_y2)*((double)a_y1-(double)a_y2)))*10));
}
return 0;
}