1. 程式人生 > 實用技巧 >分形之城

分形之城

膜拜大佬的題解:https://www.acwing.com/solution/content/16524/

遞迴+分治的思路好理解,因為這個題目中最顯著的特點就是,不斷地重複旋轉複製,也就是N級城市,可以由4個N−1級城市構造,因此我們每次可以不斷地分形N−1級,將問題範圍不斷地縮小

注意座標是按照陣列下標的方式來定的

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<ll, ll> PLL;
 5 PLL calc(ll n, ll m) {
6 if (n == 0) { 7 return make_pair(0, 0); 8 } 9 ll len = 1LL << (n - 1), cnt = 1LL << (2 * n - 2); 10 //cnt是子問題中的點的數量 11 //len是每個小單元的邊長 12 PLL pos = calc(n - 1, m % cnt); //pos表示子問題的結果 13 ll x = pos.first, y = pos.second; 14 ll z = m / cnt; //z表示處理哪一部分 15 if
(z == 0) { //處理左上角 16 return make_pair(y, x); 17 } 18 if (z == 1) { //處理右上角 19 return make_pair(x, y + len); 20 } 21 if (z == 2) { //處理右下角 22 return make_pair(x + len, y + len); 23 } 24 return make_pair(2 * len - 1 - y, len - 1 - x); //處理左下角 25 } 26 int main() {
27 int t; 28 cin >> t; 29 while (t--) { 30 ll n, a, b; 31 cin >> n >> a >> b; 32 PLL x = calc(n, a - 1); 33 PLL y = calc(n, b - 1); //都把下標變換成從0到n - 1 34 ll dx = x.first - y.first, dy = x.second - y.second; 35 double ans = (sqrt(dx * dx + dy * dy) * 10); 36 cout << fixed << setprecision(0) << ans << endl; 37 } 38 return 0; 39 }