洛谷p1605--迷宫 经典dfs

https://www.luogu.org/problemnew/show/P1605

用这种题来复习一下dfs

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

题目描述

输入输出格式

输入格式:

 

第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 复制
2 2 1
1 1 2 2
1 2
输出样例#1: 复制
1

说明

【数据规模】

1≤N,M≤5

 

最基本的dfs题目,走迷宫。

一开始还出现了一点错误,在判断方案的时候没有先判断终止条件,将计数写在了最前面。

如果终点是障碍物的话没有终止而是计数。

错误代码:

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memese(s,1,sizeof(s))
const int inf = 0x3f3f3f3f;
const int N=100005;
int vis[10][10];
int n,m,t;
int ans=0;
int x,y,x2,y2,xt,yt;
void dfs(int x,int y){
    if(x==x2&&y==y2){
        ans++;
        return ;
    }
    if(x>n||x<1||y>m||y<1) return ;
    if(vis[x][y]==1) return ;
    vis[x][y]=1;
    dfs(x+1,y);
    dfs(x-1,y);
    dfs(x,y+1);
    dfs(x,y-1);
    vis[x][y]=0;
}
int main(int argc, char * argv[]) 
{
    std::ios::sync_with_stdio(false);
    cin>>n>>m>>t;
    cin>>x>>y>>x2>>y2;
    for(int i=0;i<t;i++){
        cin>>xt>>yt;
        vis[xt][yt]=1;
    }
    dfs(x,y);
    cout<<ans<<endl;
    return 0;
}

// 3 3 2
// 1 1 3 3
// 2 2
// 3 3
// 0   //这组样例应该输出0,而上面代码输出的2

 

正确代码:

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memese(s,1,sizeof(s))
const int inf = 0x3f3f3f3f;
const int N=100005;
int vis[10][10];
int n,m,t;
int ans=0;
int x,y,x2,y2,xt,yt;
void dfs(int x,int y){
    if(x>n||x<1||y>m||y<1) return ;
    if(vis[x][y]==1) return ;
    if(x==x2&&y==y2){
        ans++;
        return ;
    }
    vis[x][y]=1;
    dfs(x+1,y);
    dfs(x-1,y);
    dfs(x,y+1);
    dfs(x,y-1);
    vis[x][y]=0;
}
int main(int argc, char * argv[]) 
{
    std::ios::sync_with_stdio(false);
    cin>>n>>m>>t;
    cin>>x>>y>>x2>>y2;
    for(int i=0;i<t;i++){
        cin>>xt>>yt;
        vis[xt][yt]=1;
    }
    dfs(x,y);
    cout<<ans<<endl;
    return 0;
}

顺便复习一遍dfs的套路:

//DFS框架

int next[4][2]={
{0,1},  //向右走
{1,0},    //向下走 
{0,-1}, //向左走 
{-1,0}, //向上走 
};   ///定义一个方向数组

void dfs(int x,int y,int step){
    if(x==p && y==q){  ///判断是否到达位置 
        if(step<min)
        min=step;  //更新最小值
        return ; 
    }
    for(k=0;k<=3;k++){
        tx=x+next[k][0];
        ty=y+next[k][1];
        if(tx<1 || tx>n ||ty<1 || ty>m)  continue;  // 判断是否越界
        if(a[tx][ty]==0 && book[tx][ty]==0){
            book[tx][ty]=1;
            dfs(tx,ty,step+1);
            book[tx][ty]=0;
        } 
    } 
    return 0;
}
上一篇:洛谷P1605走迷宫


下一篇:图论 (SPFA算法总结)