求求大家给个关注吧,你关注我我是一定会回关的!
题目描述
给定一个 N×M 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。
在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。
输入格式
第一行为三个正整数 N,M,T,分别表示迷宫的长宽和障碍总数。
第二行为四个正整数 SX,SY,FX,FY,SX,SY 代表起点坐标,FX,FY 代表终点坐标。
接下来 T 行,每行两个正整数,表示障碍点的坐标。
输出格式
输出从起点坐标到终点坐标的方案总数。
输入输出样例
输入 #1
2 2 1 1 1 2 2 1 2
输出 #1
1
说明/提示
对于 100%的数据,1≤N,M≤5,1≤T≤10,1≤SX,FX≤n,1≤SY,FY≤m。
---------------------------------------------------------------------------------------------------------------------------------
我对着一题深思熟虑,经过九九八十一的努力,我成功的编出来了一种算法,dfs!!!
奶奶道:“又讲故事,一边去!”。
想知道我为什么要讲故事看这一篇。
---------------------------------------------------------------------------------------------------------------------------------
请你先阅读线面这篇:
这时,我们就要把dfs用到新的一个境界,遍历一个地图去做完这一题。
我们先拿这个样例来举一个例子,方便寻找思路:
1 2
1 起 障
2 0 终
起:起点。
障:障碍点。
终:终点。
0:可以经过的点。
这时我们把自己想成这个代码,一开始我们站在起点上(1,1)。
这时,我们要向所处位置的四个方向进行搜索,先试着往上走。我们发现,往上走走到的坐标会越界,所以不能往上走。再试着往右走(1,2),我们发现往右边走不会越界,但是(1,2)点上有障碍,所以也不能走。再试着往下走发现(2,1)点没有任何障碍,也不会越界,于是哇哦们可以往下走……
我们发现,每次要走一步时都有四个方向可选(带你是要满足条件),于是我们也可以构建一颗和上一个全排列问题一样的递归树,每棵树最多有四个结点,分别代表可以到达的坐标:
(1,1)
/
(2,1)
/
(2,2)
可能此样例有一点特殊,因为每个点都这能到达一个点。
但是通过此样例,我们也可以得出思路。
每次递归for循环遍历四个方向,然后在for循环里判断要去到的这个点是否在界内,然后存不存在障碍。最重要的是还要判断有没有走过,不然它走过的点就会一直死循环。
那方向用这种法const int dir[4][2]={{-1, 0}, {1, 0}, {0, -1}, {0, 1}};每次用x加上组合里的第一个数,用y加上组合里的第二个数。不明白的同学在草稿纸上加一下就明白了。
详细见代码:
#include <bits/stdc++.h>
using namespace std;
const int dir[4][2]={{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
bool used[10][10], za[10][10];
int n, m, T, sx, sy, fx, fy, ans;
void dfs(int x, int y){
if(x==fx && y==fy){//到达终点ans+1
ans++;
return ;
}
for(int i=0; i<4; i++){
int cx=x+dir[i][0], cy=y+dir[i][1];//一定要用临时变量去存,不然会影响下一个循环
if(cx>=1 && cx<=n && cy>=1 && cy<=m && !used[cx][cy] && !za[cx][cy]){
used[cx][cy]=true;
dfs(cx, cy);
used[cx][cy]=false;
}
}
}
int main() {
scanf("%d%d%d%d%d%d%d", &n, &m, &T, &sx, &sy, &fx, &fy);
for(int i=0; i<T; i++){
int x, y;
scanf("%d%d", &x, &y);
za[x][y]=true;
}
used[sx][sy]=true;
dfs(sx, sy);
printf("%d", ans);
return 0;
}
有什么问题在评论区告诉我。
本期就到这,欢迎大家对我提出问题,拜拜!