【题目描述】
有一个m*n格的迷宫(表示有 m 行n 列),其中有可走的也有不可走的,如果用 1 表示可以走,0 表示不可以走,文件读入这 m*n 个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用-1表示无路)。
优先顺序:左上右下。数据保证随机生成
输入格式
第一行是两个数 m,n(1<m,n<15),接下来是 m 行 n 列由 1 和 0 组成的数据,最后两行是起始点和结束点。
输出格式
所有可行的路径,描述一个点时用 (x,y) 的形式,除开始点外,其他的都要用 `->` 表示方向。
如果没有一条可行的路则输出 -1。
样例输入 #1
5 6
1 0 0 1 0 1
1 1 1 1 1 1
0 0 1 1 1 0
1 1 1 1 1 0
1 1 1 0 1 1
1 1
5 6
样例输出 #1
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
提示
数据保证随机生成。事实上,如果 n=m=14且每个位置都是 1 的话,有 69450664761521361664274701548907358996488种路径。
题解:
这是一道很经典的搜索题。
但还是有一些小陷阱:
1.做题之后忘记判断是否有解;
2.题目对搜索前进的方向有要求:左上右下,对于不需要输出路径的题,方向是没有要求的,(方向可能会影响效率,但是不会影响到最后的结果)但是对于有路径的题,方向可能会影响解的顺序;
3.k(步数)是否偏移;
话不多说,上代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[16][16],x,y,sx,sy;
int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};
bool p=false,c[16][16];
struct node{
int x,y;
} b[100000001];
void print (int k)
{
cout<<'('<<b[1].x<<','<<b[1].y<<')';
for (int i=2;i<=k;i++)
cout<<"->("<<b[i].x<<','<<b[i].y<<')';
cout<<endl;
}
void dfs (int x,int y,int ans)
{
b[ans].x=x;
b[ans].y=y;
if (x==sx&&y==sy)
{
print (ans);
p=true;
return ;
}
for (int i=0;i<4;i++)
if (x+dx[i]<=m&&x+dx[i]>0&&y+dy[i]<=n&&y+dy[i]>0)
if (a[x+dx[i]][y+dy[i]]&&!c[x+dx[i]][y+dy[i]])
c[x][y]=true,dfs (x+dx[i],y+dy[i],ans+1),c[x][y]=false;
}
signed main ()
{
cin>>m>>n;
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
cin>>a[i][j];
cin>>x>>y>>sx>>sy;
dfs (x,y,1);
if (!p) cout<<"-1\n";
return 0;
}
这里再给大家一个基本的深搜模板
void dfs (int t)
{
if (满足输出条件)
{
输出解;
return ;
}
for (int i=0;i<尝试方法数;i++)
if (满足进一步搜索条件)
{
为进一步搜索所需要的状态打上标记;
dfs (t+1);
恢复到打标记前的状态;//也就是说的{回溯一步}
}
}
点个赞吧!