题目
TUOJ
https://sim.csp.thusaac.com/contest/38/problem/1
思路
会bfs/dfs就可以拿满
代码
可以让AI总结一下代码逻辑
(本题可以类比成我们熟悉的场景,比如"马"在棋盘上走)
这是一个使用**广度优先搜索(BFS)**计算马在棋盘上指定步数内能到达多少不同格子的程序。
一、问题设定
有一个大小为 n×n 的棋盘,棋盘坐标从 1 到 n。给定马的起点位置 (x, y) 和一个最大步数 k,要求计算马在不超过 k 步的情况下,一共能到达多少个不同的格子(包括起点)。
二、核心思路
-
马有 8 个可能的移动方向(走"日"字)
-
使用 BFS 逐层搜索,保证第一次到达某个格子时用的步数最少
-
用一个二维数组
vis记录格子是否已经被访问过,避免重复计数
三、执行流程
-
读入棋盘大小
n、最大步数k和起点坐标(x, y) -
初始化答案为 1(起点本身算一个格子)
-
将起点加入队列,标记为已访问
-
不断从队列取出位置:
-
如果当前步数已经达到
k,就不再从该位置继续扩展 -
否则尝试 8 个方向移动
-
如果新位置在棋盘内且未被访问,则标记访问、入队、答案加一
-
-
队列为空后,输出答案
四、关键点
-
BFS 保证了每个格子第一次被访问时步数最小
-
用
vis数组保证每个格子只计数一次 -
步数达到
k时停止扩展,但之前入队的同层节点仍会继续处理
cpp
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
int vis[105][105];
int dx[]={-2,-1,1,2,2,1,-1,-2};
int dy[]={1,2,2,1,-1,-2,-2,-1};
struct node{
int x,y,step;
};
void solve()
{
int n,k,x,y; cin>>n>>k>>x>>y;
int ans=1; //warn:出发点算一个
vis[x][y]=1;
queue<node>q;
q.push({x,y,0});
while(!q.empty()) {
auto t=q.front(); q.pop();
int step=t.step;
if(step==k) continue;
for(int i=0;i<8;i++){
int nx=t.x+dx[i];
int ny=t.y+dy[i];
if(vis[nx][ny]) continue;
if(nx<1||nx>n||ny<1||ny>n) continue;
vis[nx][ny]=1;
q.push({nx,ny,step+1});
ans++;
}
}
cout<<ans<<endl;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
solve();
return 0;
}