想要解决这道题,如果你知道深度优先搜索,你会更好解决;如果你不懂深度优先搜索,也可以往下看,我会讲得很清楚,如果哪里没有看懂,欢迎评论问问题,本题不管你什么时候问问题,我都会回答,为的就是大家能够没有算法基础也能搞懂这道题。
题目要求路线不能交叉,大家仔细想想,往什么方向走的时候会有交叉的可能?不错,就是往1,3,5,7方向走的时候,只有往这4个方向走,才会有交叉的可能。
我的代码尽量不浪费空间,虽然这里的数据量很小。为了让以后碰到数据量大的题仍然可以不超时,我建议不管你写题的时候数据量有多小, 都秉持尽量不要浪费空间的理念。不过我说的是尽量哈。
代码如下,注释写的很详细了,不懂欢迎评论询问!
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//dfs是深度优先搜索的意思
void dfs(int x,int y,vector<vector<int>> &a,vector<vector<bool>>& b,int dep);
int n,k;
//path用来存储临时路径,res用来春促最终路径
string path,res;
int dx[8]={-1,-1,0,1,1,1,0,-1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
//四维布尔数组用来判断交叉,如e[x1][y1][x2][y2]=true代表存在从(x1,y1)到(x2,y2)的路径,反之则不存在。
//这个四维数组的每一个维度根据N的范围,至多有10种可能,所以大小为10就够用了
bool e[10][10][10][10];
int main()
{
cin >> n >> k;
//创建一个动态二维数组,用来存储数字
vector<vector<int>> a(n,vector<int>(n));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin >> a[i][j];
}
}
//创建与a数组对应的动态二维布尔数组,用来标记已过访问过的位置
vector<vector<bool>> b(n,vector<bool>(n));
//传入(0,0)位置的坐标,两个二维数组,以及已搜索的点数1
dfs(0,0,a,b,1);
//经过搜索后,如果res不是空字符串,就输出,否则输出-1
if(res.empty())
cout << -1;
else if(res.size()==n*n-1)
cout << res;
return 0;
}
void dfs(int x,int y,vector<vector<int>> &a,vector<vector<bool>>& b,int dep)
{
//判断递归的边界条件,如果不设置这个边界,那下面的递归一旦进入,就会陷入循环永远不能结束
if(dep==n*n&&x==n-1&&y==n-1)
{
res=path;
}
//标记(x,y)已经搜索过
b[x][y]=true;
//往八个方向搜索
for(int i=0;i<8;i++)
{
//(xx,xy)表示(x,y)经过朝i方向走后达到的坐标.[xx]意思是[新x],[xy]意思是[新y];
int xx=x+dx[i],xy=y+dy[i];
//判断新坐标是否越界
if(xx<0||xx>=n||xy<0||xy>=n)
continue;
//判断到达新坐标是否会出现交叉
if(i%2!=0&&(e[xx][y][x][xy]||e[x][xy][xx][y]))
continue;
//判断新坐标是否搜索过
if(b[xx][xy])
continue;
//判断是否满足顺序的序列
if((a[x][y]+1==a[xx][xy])||(a[xx][xy]==0&&a[x][y]==k-1))
{
//一旦进入这个if语句,标记存在有从(x,y)到(xx,xy)的路径
e[x][y][xx][xy]=true;
//存进这个行走方向
path+=i+'0';
//搜索以(xx,xy)为起点的下一个点。
dfs(xx,xy,a,b,dep+1);
//一旦执行下面四行代码,则代表正在回溯
//若res不为空,说明已经找到合法路径,直接继续回溯上一层递归,不用管下面的代码了
if(!res.empty())
return;
//若res为空,说明上面那行dfs(xx,xy,a,b,dep+1)进入后没有找到合法的下一步
//于是删除上面存入的i方向,因为这个方向走了之后,(xx,xy)找不到合法的又一个新点
path.pop_back();
//同时取消这个路径标记
e[x][y][xx][xy]=false;}
}
//若八方向搜索都找不到合法的下一个点,取消访问过这个点的标记,
//同时回溯此层的上一层递归(如果这是最外层递归,则res为空字符串,返回主函数输出-1)
b[x][y]=false;
return ;
}
创作不易,求你点个赞支持一下吧 !