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; }