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