Fractal Streets POJ - 3889(递归+点的逆时针矩阵变换)

题意:传送门
题解:可以知道第 n n n等级由第 n − 1 n-1 n1等级组成而来的,首先左上角那一部分是由 n − 1 n-1 n1等级先绕左上角逆时针转 27 0 o 270^o 270o,然后与 x x x轴对称得到,第 n n n等级的右上角那块直接由第 n n n等级平移过来,第 n n n等级的右下角也是平移相对应的位置得到,第 n n n等级的左下角部分是最复杂的部分,由第 n n n等级的部分先绕左上角逆时针旋转 9 0 o 90^o 90o然后与 x x x轴对称得到,然后再平移相应的位置得到,这里的平移相应的位置都可以进行手算推导出来,重点在于点逆时针旋转 θ \theta θ度后坐标的变换,公式为: ( x , y ) ∗ [ c o s θ s i n θ − s i n θ c o s θ ] = [ x ∗ c o s θ − y ∗ s i n θ x ∗ s i n θ + y ∗ c o s θ ] \left ( x,y \right )*\begin{bmatrix} cos\theta & sin\theta\\ -sin\theta & cos\theta \end{bmatrix}=\begin{bmatrix} x*cos\theta-y*sin\theta\\ x*sin\theta+y*cos\theta \end{bmatrix} (x,y)[cosθsinθsinθcosθ]=[xcosθysinθxsinθ+ycosθ]证明自己可以画图然后自证即可。属于递归中的困难题目了。
附上代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>Pll;
int T;
ll n,a,b;
Pll calc(ll n,ll m)
{
    if(n==0)return {0,0};
    ll len=1ll<<(n-1),cnt=1ll<<(2*n-2);
    auto pos=calc(n-1,m%cnt);
    auto x=pos.first,y=pos.second;
    auto z=m/cnt;
    if(z==0)return {y,x};
    if(z==1)return {x,y+len};
    if(z==2)return {x+len,y+len};
    return {2*len-1-y,len-1-x};
}
int main()
{
    cin>>T;
    while(T--){
        cin>>n>>a>>b;
        auto ac=calc(n,a-1);
        auto bc=calc(n,b-1);
        double x=ac.first-bc.first,y=ac.second-bc.second;
        printf("%.0f\n",sqrt(x*x+y*y)*10);
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值