走迷宫(AC)

题目描述

有一个nm格的迷宫(表示有n行、m列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这nm个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用-l表示无路)。
  请统一用 左上右下的顺序拓展,也就是 (0,-1),(-1,0),(0,1),(1,0)
  输入
第一行是两个数n,m( 1 < n , m < 15 ),接下来是m行n列由1和0组成的数据,最后两行是起始点和结束点。

输出
  所有可行的路径,描述一个点时用(x,y)的形式,除开始点外,其他的都要用“->”表示方向。
  如果没有一条可行的路则输出-1。

样例输入 Copy
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
样例输出 Copy
(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)

#include<cstdio>
#define maxn 16
#include<algorithm>
#include<vector>
#include<cmath>
#include<iostream>
using namespace std;
//用一个哈希表保存某点是否被访问过,每次进入下一个点之前看是否该点已访问,越界,maze是否为1
//如果当前点是终点则输出路径,路径保存在一位数组path中
//剪枝操作 如果起点终点之间的小矩形有一行或一列全0的路则肯定没有解
//Search函数输入当前点的行号列号
//本题算法实质上是深度优先搜索DFS
int m,n;
int maze[maxn][maxn];
int sr,sc;//开始点的行,列号
int er,ec;//终点的行列号
bool hashtable[maxn][maxn]={false};
vector<int> path;//存路径
bool flag=false;//用于标记是否找到至少一条路径
void Search(int r,int c)
{
    if(!(r>m||c>n||maze[r][c]==0||hashtable[r][c]==true||r<1||c<1)){
        hashtable[r][c]=true;
        path.push_back(r);
        path.push_back(c);
    }
    else{
        return;
    }
    if(r==er&&c==ec){
            flag=true;
        for(int i=0;i<path.size();i+=2){
            if(i!=path.size()-2){
                printf("(%d,%d)->",path[i],path[i+1]);
            }
            else{
                printf("(%d,%d)\n",path[i],path[i+1]);
            }
        }
        hashtable[r][c]=false;//注意终点要回退,否则最多只会输出一条路径
        path.pop_back();
        path.pop_back();
        return ;
    }
    Search(r,c-1);//左
    Search(r-1,c);//上
    Search(r,c+1);//右
    Search(r+1,c);//下
    hashtable[r][c]=false;//回退
    path.pop_back();
    path.pop_back();
}
int main()
{
    scanf("%d %d",&m,&n);
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&maze[i][j]);
        }
    }
    scanf("%d %d",&sr,&sc);
    scanf("%d %d",&er,&ec);
    Search(sr,sc);
    if(flag==false){
        printf("-1\n");
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值