题目背景
西西艾弗岛某山脉深处出土了一台远古机器人,初步修缮后研究人员尝试操控其进行简单移动。我们需要计算在特定规则下,机器人能抵达的方格数量。
题目描述
实验场地被划分为 n×n 个方格,坐标从 (1,1) 到 (n,n)。机器人只能在这些方格间移动,不能走出场地范围。假设机器人当前位于 (x,y),接下来可以向周围八个方向跳跃移动(如果目标方格在场地范围内)。
需要注意的是,根据代码实现逻辑,这里的'八个方向'实际上对应的是类似国际象棋中'马'的走法(即横向或纵向移动一格后再移动两格)。若机器人只能跳动不超过 k 步,场地内有多少方格(包括起始位置)可以抵达?
输入格式
从标准输入读入数据。
- 第一行包含两个正整数 n 和 k,分别表示场地大小和跳动步数。
- 第二行包含两个正整数 x 和 y,表示机器人的起始位置(保证位于场地内)。
输出格式
输出一个整数,表示 k 步内可以抵达的方格总数。
样例说明
样例 1 输入:4 1 1 1 输出:3
样例 2 输入:4 2 1 1 输出:8 解释:初始位置、第一步和第二步跳跃抵达的位置总计为 8。
子任务约束
- 80% 的测试数据满足:k≤3;
- 全部测试数据满足:n、k 均大于 0 且不超过 100。
解题思路
这是一个典型的网格搜索问题,可以使用 BFS 或 DFS 来解决。考虑到递归实现的简洁性,这里采用 DFS 方案。
在 DFS 实现中,步数作为递归函数的参数传递,每深入一层代表多跳一步。我们需要维护一个访问标记数组 st,防止重复访问同一个格子导致死循环或重复计数。全局变量 cnt 用于统计已访问节点的数量。
关键点在于方向数组的定义和边界判断。由于是跳跃移动,每次移动的偏移量是固定的,需要确保新坐标仍在 [1, n] 范围内。统计的节点数包括所有经过的位置,而不仅仅是终点。
代码实现
以下是基于 C++ 的完整实现,重点展示了方向数组的定义与递归终止条件。
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n, k, x, y;
bool st[N][N]; // 记录访问状态
int dx[8] = {1, 2, 1, 2, -1, -2, -1, -2};
int dy[8] = {2, 1, -2, -1, 2, 1, -2, -1};
int cnt; // 统计已访问节点数量
void dfs(int x, int y, int num) {
st[x][y] = true;
cnt++;
if (num == k) return; // 步数用完,回溯
for (int i = 0; i < 8; i++) {
int a = x + dx[i], b = y + dy[i];
// 边界检查
if (a < 1 || a > n || b < 1 || b > n) continue;
// 未访问过才继续搜索
if (!st[a][b]) {
dfs(a, b, num + 1);
}
}
}
int main() {
cin >> n >> k >> x >> y;
dfs(x, y, 0);
cout << cnt;
return 0;
}
在实际运行中,注意递归深度不会超过 k(最大 100),因此栈溢出风险极低。对于更大的数据规模,可能需要考虑 BFS 或记忆化搜索来优化性能。
