题目描述
有一个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 且每个位置都是 11 的话,有 69450664761521361664274701548907358996488种路径。
解题方法:DFS + 回溯。
Code:
#include <iostream>
#include <stdio.h>
using namespace std;
const int N = 5000;
const int dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
int g[N][N], d[N][5];
bool map[N][N];
int n, m, sx, sy, ex, ey, f, ans;
void dfs(int x1, int y1)
{
if(x1 == ex && y1 == ey)
{
ans ++;
cout << '(' << sx << ',' << sy << ')' << "->";
for(int i = 0; i < f; i ++ )
{
if(i != f - 1) cout << '(' << d[i][0] << ',' << d[i][1] << ')' << "->";
else cout << '(' << d[i][0] << ',' << d[i][1] << ')' << endl;
}
return ;
}
for(int i = 0; i < 4; i ++ )
{
int x = x1 + dx[i], y = y1 + dy[i];
if(x >= 1 && x <= n && y >= 1 && y <= m && !map[x][y] && g[x][y] == 1)
{
map[x][y] = true;
d[f][0] = x, d[f][1] = y; //记录坐标
f ++;
dfs(x, y);
map[x][y] = false;
f --;
}
}
}
signed main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ )
{
for(int j = 1; j <= m; j ++ ) scanf("%d", &g[i][j]);
}
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
map[sx][sy] = true; //标记起点
dfs(sx, sy);
if(ans == 0) cout << -1 << endl;
}