Fractal Streets POJ - 3889 分治+遞迴座標轉換
阿新 • • 發佈:2020-12-09
技術標籤:分治
城市的規劃在城市建設中是個大問題。
不幸的是,很多城市在開始建設的時候並沒有很好的規劃,城市規模擴大之後規劃不合理的問題就開始顯現。
而這座名為 Fractal 的城市設想了這樣的一個規劃方案,如下圖所示:
當城區規模擴大之後,Fractal 的解決方案是把和原來城區結構一樣的區域按照圖中的方式建設在城市周圍,提升城市的等級。
對於任意等級的城市,我們把正方形街區從左上角開始按照道路標號。
雖然這個方案很爛,Fractal 規劃部門的人員還是想知道,如果城市發展到了等級 N,編號為 A 和 B 的兩個街區的直線距離是多少。
街區的距離指的是街區的中心點之間的距離,每個街區都是邊長為 10 米的正方形。
第一行輸入正整數n,表示測試資料的數目。以下n行,輸入n組測試資料,每組一行。每組資料包括三個整數 N,A,B, 表示城市等級以及兩個街區的編號,整數之間用空格隔開。
輸出格式
一共輸出n行資料,每行對應一組測試資料的輸出結果,結果四捨五入到整數。
資料範圍
1≤N≤31
1≤A,B≤22N,
1≤n≤1000
輸入樣例:
3
1 1 2
2 16 1
3 4 33
輸出樣例:
10
30
50
#include <iostream>
#include <bits/stdc++.h>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
pair <ll,ll>solve(ll n,ll m)
{
if(n==0)return make_pair(1,1);
ll len=1<<(n-1),cnt=1<<(2*n-2);//lenshimeiyixiaokuaide changdu//cntshimeisifenzhiyide shuliang;
pair<ll,ll>pos = solve(n-1,m%cnt);
ll x=pos.first,y=pos.second;
ll k=m/cnt;
if(k==0)return make_pair(y,x);//diyiqunjianshigaunyu duijiaoxianduichen;
if(k==1)return make_pair(x,y+len);//dierqujian
if(k==2)return make_pair(x+len,y+len);
if(k==3)return make_pair(len+len-y+1,len-x+1);//guandufanduijiaoxianduichen;
}
int main()
{
ll t,n,a,b;
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld%lld",&n,&a,&b);
pair<ll,ll>id1=solve(n,a-1);
pair<ll,ll>id2=solve(n,b-1);//每次都減少一是為啦待會可以直接用除法得到他們在那個四分之一處。
ll x = id1.first-id2.first;
ll y = id1.second-id2.second;
a=x*x+y*y;
double ans=sqrt(a);
printf("%.0lf\n",ans*10);
}
return 0;
}