洛谷:P1238 走迷宫
https://www.luogu.com.cn/problem/P1238
描述:
有一个 m×n 格的迷宫(表示有 m 行、n 列),其中有可走的也有不可走的,如果用 1 表示可以走,0 表示不可以走,文件读入这 m×n 个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用−1 表示无路)。
优先顺序:左上右下。数据保证随机生成。
输入格式:
第一行是两个数,m,n(1< m,n<15),接下来是 m 行 n 列由 1 和 0 组成的数据,最后两行是起始点和结束点。
输出格式:
所有可行的路径,描述一个点时用 (x,y) 的形式,除开始点外,其他的都要用 -> 表示方向。
如果没有一条可行的路则输出 −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)->(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)
分析:
深搜的思路,对于这种要输出每一种情况的题,需要进行状态数组的更新与回溯,曾经产生过的贡献在改变dfs方向时要取消掉,这样才能做到不重不漏。
对于这道题要回溯的地方就是是否到达过该地方和状态数组的索引。
注意起始坐标在一开始就要标记为0,不然在dfs的过程中不会有体现。
代码如下:
#include<iostream>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdio>
#include<queue>
using namespace std;
class road
{
public:
int x;
int y;
};
int m,n;
int ma[20][20] = {
0};
int sx,sy;
int ex,ey;
int changex[4] = {
0, -1, 0, 1};
int changey[4] = {
-1, 0, 1, 0};
int q = 1;
bool judge = false;
road R[1000];
void dfs(int x, int y)
{
if(x == ex - 1 && y == ey - 1)
{
for(int i = 0;i < q;i++)
{
if(i == q - 1)
{
cout<<"("<<R[i].x + 1<<","<<R[i].y + 1<<")"<<endl;
}
else
{
cout<<"("<<R[i].x + 1<<","<<R[i].y + 1<<")"<<"->";
}
}
judge = true;
return;
}
for(int i = 0;i < 4;i++)
{
int newx = x + changex[i];
int newy = y + changey[i];
if(newx >=0 && newx < m && newy >= 0 && newy < n && ma[newx][newy] == 1)
{
ma[newx][newy] = 0;
R[q].x = newx;
R[q].y = newy;
q++;
dfs(newx, newy);
q--;
ma[newx][newy] = 1;
}
}
}
int main()
{
cin>>m>>n;
for(int i = 0;i < m;i++)
{
for(int j = 0;j < n;j++)
{
cin>>ma[i][j];
}
}
cin>>sx>>sy;
cin>>ex>>ey;
R[0].x = sx - 1;
R[0].y = sy - 1;
ma[0][0] = 0;
dfs(sx - 1, sy - 1);
if(!judge)
{
cout<<"-1"<<endl;
}
return 0;
}