题目描述
给定一个 N×MN×M 方格的迷宫,迷宫里有 TT 处障碍,障碍处不可通过。
在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。
输入格式
第一行为三个正整数 N,M,TN,M,T,分别表示迷宫的长宽和障碍总数。
第二行为四个正整数 SX,SY,FX,FYSX,SY,FX,FY,SX,SYSX,SY 代表起点坐标,FX,FYFX,FY 代表终点坐标。
接下来 TT 行,每行两个正整数,表示障碍点的坐标。
输出格式
输出从起点坐标到终点坐标的方案总数。
输入输出样例
输入 #1
2 2 1 1 1 2 2 1 2
输出 #1
1
说明/提示
对于 100%100% 的数据,1≤N,M≤51≤N,M≤5,1≤T≤101≤T≤10,1≤SX,FX≤n1≤SX,FX≤n,1≤SY,FY≤m1≤SY,FY≤m。
此题思路
这题其实有几种解法,一个深搜(dfs - Depth First Search),一个广搜(bfs-Breadth First Search)那我们先讲一讲深搜吧
深搜
深搜其实就是递归题目不是说了吗,起点是(1,1),重点为(n,m)那我们就把起始值设为dfs(1,1)然后每次都判断是不是为(n,m)然后遍历4个方向上下左右,我们就定义一个dx和dy来存储
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
这就是几个方向,然后在循环里定义一个X和Y为下一个方向的位置然后判断一下X和Y有没有越界如果没有在判断一下a[X][Y]是不是可走的路。如果是则继续递归下去dfs(X,Y)。
void dfs(int x,int y)
{
if(x==n&&y==m)
{
p=true;
return;
}
a[x][y]=1;
for(int i=0;i<4;i++)
{
int X=x+dx[i];
int Y=y+dy[i];
if(X>0&&X<=n&&Y>0&&Y<=m)
{
if(a[X][Y]==0)
{
dfs(X,Y);
}
}
}
}
这就是dfs里面的代码,完整的就是:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[110][110];
bool p;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
void dfs(int x,int y)
{
if(x==n&&y==m)
{
p=true;
return;
}
a[x][y]=1;
for(int i=0;i<4;i++)
{
int X=x+dx[i];
int Y=y+dy[i];
if(X>0&&X<=n&&Y>0&&Y<=m)
{
if(a[X][Y]==0)
{
dfs(X,Y);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
char x;
cin>>x;
if(x=='#')
{
a[i][j]=1;
}
}
}
if(a[1][1]==1||a[n][m]==1)
{
cout<<"No";
return 0;
}
dfs(1,1);
if(p)
{
cout<<"Yes";
}
else
{
cout<<"No";
}
return 0;
}
学会了吗?
广搜
广搜其实就是定义一个queue的队列,然后定义一个结构体
struct node
{
int x;//此时的横坐标
int y;//此时的竖坐标
};
然后将那个队列q给定义成node类型(有点不想写了......)
然后呢在bfs中定义一个node类型的w为起始点w.x=1,w.y=1
然后呢将w入队,接下来一个while循环直到q队列为空,那就代表没法到达输出"No"
在while循环中w=q.front()为头一个然后去除为元素,然后看一下w是不是为终点,如果是则输出"Yes",如果不是则和dfs一样遍历四个方向(上下左右)然后定义一个k为王此方向后的位置
node k={w.x+dx[i],w.y+dy[i]};
然后和dfs一样判断边界是否超了在判断可走并且没有标记过则标记一下为1然后入队
void bfs()
{
node w={1,1};
vis[1][1]=1;
q.push(w);
while(!q.empty())
{
w=q.front();
q.pop();
if(w.x==n1&&w.y==m1)
{
cout<<"Yes";
return;
}
for(int i=1;i<=4;i++)
{
node k={w.x+dx[i],w.y+dy[i]};
if(k.x>=1&&k.y>=1&&k.x<=n1&&k.y<=m1&&a[k.x][k.y]=='.'&&vis[k.x][k.y]==0)
{
vis[k.x][k.y]=1;
q.push(k);
}
}
}
cout<<"No";
return;
}
这就是bfs里的内容,学会了吗?以下是全文!
#include<bits/stdc++.h>
using namespace std;
const int N=101;
char a[N][N];
int n1,m1,vis[N][N];
int dx[5]={0,1,0,-1,0};
int dy[5]={0,0,-1,0,1};
struct node
{
int x;
int y;
};
queue<node>q;
void bfs()
{
node w={1,1};
vis[1][1]=1;
q.push(w);
while(!q.empty())
{
w=q.front();
q.pop();
if(w.x==n1&&w.y==m1)
{
cout<<"Yes";
return;
}
for(int i=1;i<=4;i++)
{
node k={w.x+dx[i],w.y+dy[i]};
if(k.x>=1&&k.y>=1&&k.x<=n1&&k.y<=m1&&a[k.x][k.y]=='.'&&vis[k.x][k.y]==0)
{
vis[k.x][k.y]=1;
q.push(k);
}
}
}
cout<<"No";
return;
}
int main()
{
cin>>n1>>m1;
for(int i=1;i<=n1;i++)
{
for(int j=1;j<=m1;j++)
{
cin>>a[i][j];
}
}
if(a[1][1]=='#'||a[n1][m1]=='#')
{
cout<<"No";
return 0;
}
bfs();
return 0;
}
真的真的不想写注释啊!完全写不动啊!
大家学会了吗?点个关注呗!(大佬勿喷!)