链接 Philosopher’s Walk
题意:
给出如下图 n * n 的网格 ,n 一定为 2的幂次(n
≤
\leq
≤ 2 ^ 15),给出运动轨迹,求第 k 步所在网格的位置。
思路:
- 蓝桥被考过一道类似的题目 , 大概就是找出这个图形的几个基本形状,然后dfs就可以了 , 例如 最大的 W3图形,我们可以对步数除 16,判断在四个格子中的哪一个格子,并判断其基本形状 ,dfs的时候维护 当前位置 , 网格大小 ,基本形状,剩余步数就可以了。
- 这个图形一共四种基本形状
代码:
#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);
}