方格迷宫(矩阵加回溯)

问题 J: 方格迷宫

 

题目描述

设有一个N*N(2<=N<10)方格的迷宫,入口和出口分别在左上角和右上角。迷宫格子中分别放010表示可通,1表示不能,入口和出口处肯定是0。迷宫走的规则如下所示:即从某点开始,有八个方向可走,前进方格中数字为0时表示可通过,为1时表示不可通过,要另找路径。找出所有从入口(左上角)到出口(右上角)的路径(不能重复),输出路径总数,如果无法到达,则输出0

输入

第一行是1个正整数n(2<=n<10),表示迷宫规模是n*n的。接下来n行是一个n*n0-1矩阵。

输出

找出所有从入口(左上角)到出口(右上角)的路径(不能重复),输出路径总数,如果无法到达,则输出0

样例输入

3

0 0 0

0 1 1

1 0 0

样例输出

2



纯水题,只是我做的时候还不会用BFS,所以用了回溯加矩阵,用一个2n*2n的矩阵存储点,其中一半用来存点,一般用来存点与点之间的关系,本题是用来标记两点是否连通过。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int N=25;
int a[N][N]; /*构建矩阵*/
int n;
int sum=0;
void dfs(int x,int y){
    if(x==1&&y==n) sum++;                   /*返回条件,注意是到右上的点*/
    else {
        if(x+1<=n&&y+1<=n&&a[x*2][y*2]<=0&&
           !a[(x+1)*2-1][(y+1)*2-1]){       /*可以通过的条件,用数组存储运动更好*/
            a[(x+1)*2-1][(y+1)*2-1]=1;      /*点的标记*/
            a[x*2][y*2]=1;                  /*点与点之间状态,*/
            dfs(x+1,y+1);                   /*注意:对角线经过的点状态是不同的,*/
            a[(x+1)*2-1][(y+1)*2-1]=0;      /*下面是用-1代表右上角与左下角的运动,*/        
            a[x*2][y*2]=0;                  /*1代表左上角与右下角的运动*/
        }
        if(y+1<=n&&a[x*2-1][2*y]==0&&
           !a[x*2-1][(y+1)*2-1]){
            a[x*2-1][(y+1)*2-1]=1;
            a[x*2-1][2*y]=1;
            dfs(x,y+1);
            a[x*2-1][(y+1)*2-1]=0;
            a[x*2-1][2*y]=0;
        }
        if(x-1>=1&&y+1<=n&&a[(x-1)*2][y*2]>=0&&
           !a[(x-1)*2-1][(y+1)*2-1]){
            a[(x-1)*2-1][(y+1)*2-1]=1;
            a[(x-1)*2][y*2]=-1;             /*左下到右上*/
            dfs(x-1,y+1);
            a[(x-1)*2-1][(y+1)*2-1]=0;
            a[(x-1)*2][y*2]=0;
        }
        if(x+1<=n&&a[x*2][2*y-1]==0&&
           !a[(x+1)*2-1][y*2-1]){
            a[(x+1)*2-1][y*2-1]=1;
            a[x*2][2*y-1]=1;
            dfs(x+1,y);
            a[(x+1)*2-1][y*2-1]=0;
            a[x*2][2*y-1]=0;
        }
        if(x-1>=1&&a[(x-1)*2][2*y-1]==0&&
           !a[(x-1)*2-1][y*2-1]){
            a[(x-1)*2-1][y*2-1]=1;
            a[(x-1)*2][2*y-1]=1;
            dfs(x-1,y);
            a[(x-1)*2][2*y-1]=0;
            a[(x-1)*2-1][y*2-1]=0;
        }

        if(y-1>=1&&a[2*x-1][2*y-2]==0&&
           !a[x*2-1][(y-1)*2-1]){
            a[x*2-1][(y-1)*2-1]=1;
            a[2*x-1][2*y-2]=1;
            dfs(x,y-1);
           a[x*2-1][(y-1)*2-1]=0;
            a[2*x-1][2*y-2]=0;
        }
        if(x+1<=n&&y-1>=1&&a[x*2][(y-1)*2]>=0&&
           !a[(x+1)*2-1][(y-1)*2-1]){
            a[(x+1)*2-1][(y-1)*2-1]=1;
            a[x*2][(y-1)*2]=-1;             /*右上到左下*/
            dfs(x+1,y-1);
            a[(x+1)*2-1][(y-1)*2-1]=0;
            a[x*2][(y-1)*2]=0;
        }

        if(x-1>=1&&y-1>=1&&a[(x-1)*2][(y-1)*2]<=0&&
           !a[(x-1)*2-1][(y-1)*2-1]){
            a[(x-1)*2-1][(y-1)*2-1]=1;
            a[(x-1)*2][(y-1)*2]=1;
            dfs(x-1,y-1);
            a[(x-1)*2-1][(y-1)*2-1]=0;
            a[(x-1)*2][(y-1)*2]=0;
        }
    }
}
int main()
{
    sum=0;
    scanf("%d",&n);
    memset(a,0,sizeof(a));                 /*矩阵清零*/
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&a[2*i-1][2*j-1]);
    a[1][1]=1;
    dfs(1,1);                              /*调用递归*/
    printf("%d\n",sum);
    return 0;
}

只是自己摸索出来的一种矩阵用法,因为BFS太常见,所以就不发BFS,这道题还是BFS比较好用,不用考虑很多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值