【题目大意】
社区的设计有一种特殊的规律,从左上角起沿着道路给房子编号,求给定编号的两间房子的距离。
【思路分析】
分析可得社区的设计规律,编号为$n$,即有$4^n$个小格子,每$4^{n-1}$个小格子为一个大格子,即整个图分为四部分,其中右上和右下两部分与编号为$n-1$的相同,左上是顺时针旋转90度的结果,左下是逆时针旋转90度的结果。
代码实现的过程中注意一下这几种不同的情况,计算出坐标后直接求距离。
【代码实现】
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #define rg register 5 #define go(i,a,b) for(rg int i=a;i<=b;i++) 6 #define ll long long 7 using namespace std; 8 int T,n,h,o; 9 ll ksm[25]; 10 int dfs(int num,int id,int &x,int &y){ 11 if(num==1) 12 switch(id){ 13 case 1:{x=1,y=1;return 0;} 14 case 2:{x=1,y=2;return 0;} 15 case 3:{x=2,y=2;return 0;} 16 case 4:{x=2,y=1;return 0;} 17 } 18 int size=ksm[num-1]*ksm[num-1]; 19 if(id<=size) return dfs(num-1,id,y,x),0;//左上 20 if(id<=size*2) return dfs(num-1,id-size,x,y),y+=ksm[num-1],0;//右上 21 if(id<=size*3) return dfs(num-1,id-size*2,x,y),x+=ksm[num-1],y+=ksm[num-1],0;//右下 22 return dfs(num-1,id-size*3,y,x),x=ksm[num]+1-x,y=ksm[num-1]+1-y,0;//左下 23 } 24 int main(){ 25 scanf("%d",&T); 26 ksm[0]=1;go(i,1,20) ksm[i]=ksm[i-1]<<1;//预处理 27 while(T--){ 28 scanf("%d%d%d",&n,&h,&o); 29 int x1,x2,y1,y2; 30 dfs(n,h,x1,y1);dfs(n,o,x2,y2);//找出给定的两间房子的坐标 31 double as=sqrt((double)(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))*10+0.5; 32 int ans=(int)as; 33 printf("%d ",ans); 34 } 35 return 0; 36 }