Gym 101667 Problem F Philosopher’s Walk (分形 + dfs)

链接 Philosopher’s Walk
题意:
给出如下图 n * n 的网格 ,n 一定为 2的幂次(n ≤ \leq 2 ^ 15),给出运动轨迹,求第 k 步所在网格的位置。
在这里插入图片描述
思路:

  1. 蓝桥被考过一道类似的题目 , 大概就是找出这个图形的几个基本形状,然后dfs就可以了 , 例如 最大的 W3图形,我们可以对步数除 16,判断在四个格子中的哪一个格子,并判断其基本形状 ,dfs的时候维护 当前位置 , 网格大小 ,基本形状,剩余步数就可以了。
  2. 这个图形一共四种基本形状
    在这里插入图片描述
    代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#define next ne
using namespace std;
typedef long long ll;
const int maxn= 1e3+7 ;
const int mod = 1e9 + 7;
int k,n,ans1 = -1,ans2 = -1;
void dfs(int lei,int w,int nx,int ny,int step){
    if(ans1 != -1 && ans2 != -1) return ;
    if(step == 0){
        ans1 = nx,ans2 = ny;
        return;
    }
    int s = w * w / 4;
    if(lei == 1){
        int ge = step / s + 1;
        if(ge == 1){
            dfs(3 , w / 2 , nx,ny,step);
        }
        if(ge == 2){
            dfs(1 , w / 2 , nx + w / 2 , ny , step - s);
        }
        if(ge == 3){
            dfs(1 , w / 2 , nx + w / 2 , ny + w / 2 , step - 2 * s);
        }
        if(ge == 4){
            dfs(2 , w / 2 , nx + w / 2 - 1 , ny + w - 1, step -  3 * s);
        }
    }
    if(lei == 2){
        int ge = step / s + 1;
        if(ge == 1){
            dfs(4 , w / 2 , nx,ny,step);
        }
        if(ge == 2){
            dfs(2 , w / 2 , nx, ny - w / 2 , step - s);
        }
        if(ge == 3){
            dfs(2 , w / 2 , nx - w / 2 , ny - w / 2 , step - 2 * s);
        }
        if(ge == 4){
            dfs(1 , w / 2 , nx - w + 1 , ny - w / 2 + 1 , step -  3 * s);
        }
    }
    if(lei == 3){
        int ge = step / s + 1;
        if(ge == 1){
            dfs(1 , w / 2 , nx,ny,step);
        }
        if(ge == 2){
            dfs(3 , w / 2 , nx , ny + w / 2 , step - s);
        }
        if(ge == 3){
            dfs(3 , w / 2 , nx + w / 2 , ny + w / 2 , step - 2 * s);
        }
        if(ge == 4){
            dfs(4 , w / 2 , nx + w - 1 , ny + w / 2 - 1 , step -  3 * s);
        }
    }
    if(lei == 4){
        int ge = step / s + 1;
        if(ge == 1){
            dfs(2 , w / 2 , nx,ny,step);
        }
        if(ge == 2){
            dfs(4 , w / 2 , nx - w / 2 , ny , step - s);
        }
        if(ge == 3){
            dfs(4 , w / 2 , nx - w / 2 , ny - w / 2 , step - 2 * s);
        }
        if(ge == 4){
            dfs(3 , w / 2 , nx - w / 2 + 1 , ny - w + 1 , step -  3 * s);
        }
    }
}
int main() {
    scanf("%d%d",&k,&n);
    dfs(3 , k , 1 , 1 , n - 1);
    printf ("%d %d\n",ans1,ans2);
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值