hi!大家好:
最近几天看了问答,发现有一些人在刷采纳,我就不说是谁了,建议官方处理一下;
好了,回到正题,最近几天,有个朋友问我了很多BFS的题
我打着打着就有点蒙,难的题对了,简单的题错了。。。就离谱;
于是聪明(nt)的作者就想做点别的找找自信;
随便选了一道题:马走日
题目介绍:
马在中国象棋以日字形规则移动。
请编写一段程序,给定 n×m大小的棋盘,以及马的初始位置 (x, y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。
输入格式
第一行为整数 T(T<10),表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标 n,m,x,y。
0≤x≤n−1
0≤y≤m−1
m<10,n<10
输出格式
每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,0 为无法遍历一次;
思路:
这题就是普通的DFS加判断而已,同时数据也不大,所以不需要过多考虑;
代码段逐步理解:
定义变量:
#include<bits/stdc++.h>
using namespace std;
int n,m,ans;
int dx[10] = {1,2,-1,-2,-1,-2, 1, 2};//方向——正常如果无堵马脚,马有八方向,即八个点
int dy[10] = {2,1, 2, 1,-2,-1,-2,-1};
bool vis[15][15];//判断整个棋盘是否都走过了的数组
判断是否整个棋盘的点都被标记为1(被走到过):
bool check()
{
for (int i=0;i<n;i++)
{
for (int j=0;j <m;j++)
{
if (!vis[i][j]) return false;
}
}
return true;
}
DFS函数(核心):
void dfs(int x, int y)
{
if (check())
{
ans++;
return;
}
for (int i = 0; i < 8; i++) //八方向判断
{
int tx=x+dx[i];
int ty=y+dy[i];
if (0<=tx&&tx<n&&0<=ty&&ty<m&&!vis[tx][ty])//未越界且没走过,才继续dfs
{
vis[tx][ty]=true;//设为走过,以免回走
dfs(tx,ty);
vis[tx][ty]=false;//清除走过标记
}
}
}
main(输入、输出):
int main()
{
int x1,y1;
int t;
cin>>t;
while(t--)
{
cin>>n>>m>>x1>>y1;
ans=0;
memset(vis,false,sizeof(vis));//每一组数据测试前清除标记
vis[x1][y1]=true;
dfs(x1,y1);
cout<<ans<<endl;
}
return 0;
}
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,ans;
int dx[10]={1,2,-1,-2,-1,-2, 1, 2};
int dy[10]={2,1, 2, 1,-2,-1,-2,-1};
bool vis[15][15];
bool check()
{
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
if (!vis[i][j]) return false;
return true;
}
void dfs(int x, int y)
{
if (check())
{
ans++;
return;
}
for (int i=0;i<8;i++)
{
int tx=x+dx[i];
int ty=y+dy[i];
if (0<=tx&&tx<n&&0<=ty&&ty<m&&!vis[tx][ty])
{
vis[tx][ty]=true;
dfs(tx,ty);
vis[tx][ty]=false;
}
}
}
int main()
{
int x1,y1;
int t;
cin>>t;
while(t--)
{
cin>>n>>m>>x1>>y1;
ans=0;
memset(vis,false,sizeof(vis));
vis[x1][y1]=true;
dfs(x1,y1);
cout<<ans<<endl;
}
return 0;
}

本文介绍了如何使用C++解决马走日问题,通过深度优先搜索(DFS)算法,计算在给定的n×m棋盘上,马从特定位置出发遍历所有点的不同路径数。文章详细讲解了思路、代码逻辑,并提供了AC代码。

5332

被折叠的 条评论
为什么被折叠?



