题目背景
西西艾弗岛某山脉深处出土了一台远古机器人,具体年代已不可考。初步修缮后,研究人员尝试操控机器人进行些简单的移动。
题目描述
整个实验场地被划分为 n×n 个方格,从 (1,1) 到 (n,n) 进行编号。机器人只能在这些方格间移动,不能走出场地范围。如下图所示,假设机器人当前位于 (x,y),那么接下来可以向周围八个方向跳跃移动(如果目标方格在场地范围内):

若机器人只能跳动不超过 k 步,场地内有多少方格(包括起始位置)可以抵达?
输入格式
从标准输入读入数据。
输入的第一行包含空格分隔的两个正整数 n 和 k,分别表示场地大小和跳动步数。
输入的第二行包含空格分隔的两个正整数 x 和 y,表示机器人的起始位置(保证位于场地内)。
输出格式
输出到标准输出。
输出一个整数,表示 k 步内可以抵达的方格总数。
样例 1 输入
4 1 1 1
样例 1 输出
3
样例 2 输入
4 2 1 1
样例 2 输出
8
样例 2 解释
如下图所示,初始位置、第一步和第二步跳跃抵达的位置总计为 8。

子任务
80% 的测试数据满足:k≤3; 全部的测试数据满足:n、k 均大于 0 且不超过 100。
解题思路
这道题本质上是一个典型的图遍历问题。我们可以把每个方格看作图中的一个节点,合法的跳跃动作就是节点之间的边。因为需要统计 k 步内能到达的所有点,使用深度优先搜索(DFS)或者广度优先搜索(BFS)都很合适。
在实际编码时,我倾向于用 DFS,因为它实现起来比较直观。我们需要维护一个访问标记数组 st,防止重复访问同一个格子导致死循环或重复计数。全局变量 cnt 用来记录已经访问过的节点数量。
关于移动方向,题目图示暗示了这是一个马字形的跳法(类似国际象棋中的马),即横向走 1 格纵向走 2 格,或者横向 2 格纵向 1 格。这可以通过两个方向数组 dx 和 dy 来统一处理。
边界判断是这类题目的关键。每次递归前都要检查新坐标是否在 [1, n] 范围内,越界则跳过。另外要注意,步数 num 达到 k 时停止递归,但当前这一步所在的格子依然要计入总数。
代码实现
下面是完整的 C++ 实现,包含了必要的注释和格式化:
#include <bits/stdc++.h>
using namespace std;
const int N = ;
n, k, x, y;
st[N][N];
cnt;
dx[] = {, , , , , , , };
dy[] = {, , , , , , , };
{
st[x][y] = ;
cnt++;
(num == k) ;
( i = ; i < ; i++) {
nx = x + dx[i];
ny = y + dy[i];
(nx < || nx > n || ny < || ny > n) ;
(!st[nx][ny]) {
(nx, ny, num + );
}
}
}
{
cin >> n >> k >> x >> y;
(x, y, );
cout << cnt;
;
}

