P1605 迷宫

求求大家给个关注吧,你关注我我是一定会回关的!

题目描述

给定一个 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!!!

奶奶道:“又讲故事,一边去!”。

想知道我为什么要讲故事看这一篇。

P2249 【深基13.例1】查找-CSDN博客

---------------------------------------------------------------------------------------------------------------------------------

请你先阅读线面这篇:

P1706 全排列问题-CSDN博客

这时,我们就要把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;
}

有什么问题在评论区告诉我。

本期就到这,欢迎大家对我提出问题,拜拜!

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
求解迷宫问题可以使用深度优先搜索(DFS)或广度优先搜索(BFS)算法。 以DFS为例,可以用递归函数来实现。具体步骤如下: 1. 定义一个二维数组maze表示迷宫地图,元素值为0表示该位置可以通行,为1表示该位置为障碍物不可通行。 2. 定义一个二维数组visited表示迷宫地图中的每个位置是否已经访问过,初始值为False。 3. 定义一个函数DFS(x, y)表示从坐标为(x, y)的位置开始搜索迷宫。如果到达终点位置,则输出路径,并结束搜索。否则,按照上下左右的顺序依次判断相邻位置是否可以通行,如果可以通行且未被访问过,则递归调用DFS函数继续搜索。 4. 在程序主函数中调用DFS函数并传入起点坐标。 以下是程序实现的示例代码: ```python # 定义迷宫地图 maze = [[0, 1, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 1, 0]] # 定义迷宫地图的大小 n = len(maze) m = len(maze[0]) # 定义visited数组 visited = [[False for j in range(m)] for i in range(n)] # 定义搜索函数 def DFS(x, y): # 到达终点位置 if x == n-1 and y == m-1: print("找到一条路径") return # 标记该位置已被访问 visited[x][y] = True # 按上下左右的顺序依次判断相邻位置是否可以通行 if x > 0 and not visited[x-1][y] and maze[x-1][y] == 0: DFS(x-1, y) # 向上搜索 if x < n-1 and not visited[x+1][y] and maze[x+1][y] == 0: DFS(x+1, y) # 向下搜索 if y > 0 and not visited[x][y-1] and maze[x][y-1] == 0: DFS(x, y-1) # 向左搜索 if y < m-1 and not visited[x][y+1] and maze[x][y+1] == 0: DFS(x, y+1) # 向右搜索 # 取消该位置的标记 visited[x][y] = False # 调用搜索函数并传入起点坐标 DFS(0, 0) ``` 以上代码输出结果为: ``` 找到一条路径 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值