P1605 迷宫

luogu P1605 迷宫

 这是经典的深度优先搜索(DFS)案例。

题目描述:给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

输入:第一行n、m和t,n为行,m为列,t为障碍总数。第二行起点坐标(sx,sy),终点坐标(fx,fy)。接下来t行,每行为障碍点的坐标。

输出:给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。

输入输出样例

输入样例

2 2 1

1 1 2 2 

1 2

输出样例

1

 题目大意:从(sx,sy)点走到(fx,fy)点,其中有 t 处障碍,我们设每个障碍点的坐标为(t1_i,t2_i),求有几条路径。

深度优先搜索(DFS)大体结构:如果已经到了终点,方案数就加1,如果没有到终点,那么就继续搜索

每个方格最多经过1次,他的本意是不能向回走,我们先要建一个二维数组b用来判断(x,y)点有没有走过。

我们走到(x,y)点需要把b[x][y]标记为1(已经走过),搜索完成后,回溯,再把代表(x,y)点有没有走过的b[x][y]标记为0(没有走过)。

如何判断(x,y)点是不是障碍点呢?

我们建一个二维数组a,如果(x,y)点是障碍点,那么就要把 a[x][y] 标记为1,表示(x,y)点是障碍点,不能走;如果(x,y)点不是障碍点,标记为0,表示(x,y)点不是障碍点,可以走。

有了二维数组a和b,就可以解决走没走和障碍点的问题。

那么如何向上下左右移动呢?

我们先看一个例子(如下图):

假设我们在(1,1)点。

向左移动,会移动到(1,0)点,x坐标不变,y坐标减1

向右移动,会移动到(1,2)点,x坐标不变,y坐标加1

向上移动,会移动到(0,1)点,x坐标减1,y坐标不变

向下移动,会移动到(2,1)点,x坐标加1,y坐标不变

所以就得出了dx数组和dy数组(坐标数组)

long long int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};

然后用for循环枚举四个方向就行了。

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
long long int n,m,t,sx,sy,fx,fy;
//n为行,m为列,t为障碍数,sx与sy为起点坐标,fx与fy为终点坐标 
long long int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
//方向坐标 
long long int ans=0,a[101][101],b[101][101],t1,t2;
//ans为方案总数,t1与t2为障碍坐标 
//a[i][j]表示地图上的 (i,j) 点是否为障碍,如果是障碍点标记为1,不是障碍点标记为0
//b[i][j]表示地图上的 (i,j) 点是否走过
void dfs(long long int idx,long long int idy)
{
    if(idx==fx&&idy==fy)//是否到达终点 
    {
        ans++;//方案数加1 
    }
    else//没有到达终点 
    {
        for(int i=0;i<4;i++)//枚举四个方向(上下左右) 
        {
            long long int x=idx+dx[i],y=idy+dy[i];
            if((b[x][y]==0&&a[x][y]==0)&&(x>0&&x<=n&&y>0&&y<=m))
            //判断 (x,y) 点是否走过,以及是否为障碍,和是否在边界里(不能超出边界) 
            {
                b[x][y]=1;//标记为1,表示已经走过 
                dfs(x,y);
                b[x][y]=0;//回溯,标记为0,表示没有走过 
            }
        }
    }
}
int main()
{
    scanf("%lld %lld %lld",&n,&m,&t);//输入 
    scanf("%lld %lld %lld %lld",&sx,&sy,&fx,&fy);//输入起点坐标与终点坐标 
    b[sx][sy]=1;//每个方格只能走1次,所以也不能回到起点 
    for(int i=0;i<t;i++)
    {
        scanf("%lld %lld",&t1,&t2);//障碍物坐标 
        a[t1][t2]=1;//标记为1,不可以走 
    }
    dfs(sx,sy);//搜索 
    printf("%lld",ans);//输出方案总数 
    return 0;
}

(第一次写博客,讲的不太详细,请谅解)

原文地址:https://www.cnblogs.com/wswxx/p/13287062.html