总结

洛谷P1605迷宫题解:

题目背景
给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

题目描述

输入格式
第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。

输出格式
给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。
输入输出样例
输入
2 2 1
1 1 2 2
1 2
输出
1
说明/提示
【数据规模】

1≤N,M≤5

洛谷P1605迷宫题解:
题意:
在一个N*M方格的迷宫中 起点与终点已标记(坐标) 求:
从起点坐标到终点坐标的方案总数
注意:!!!
1.移动的方式有上下左右
2.每个方格最多只能经过一次 且每次移动只能一个方格
3.迷宫中存在障碍 起点无障碍 !!!终点题目未指明无障碍 所以说终点可能存在障碍(容易被忽略!!!)
4.边界问题:无法越界

思路:
题目中问的是方案的总数(即满足题意且达到出口的方法总数)相当于呢 就是把所有路线都走一遍 再把满足题意的路线挑出来就是答案啦 者很明显是盲目的搜索 符合dfs思想 采用深度优先搜索(void dfs(int x,int y)参数为坐标 注:什么在变化 什么便是参数 此题由于在迷宫中移动 移动位置的表示为坐标 所以坐标为此题的参数)思想:从一源节点开始 向前摸索 路过一个节点 若节点的前方无节点 辣么就退回上一个节点 寻转另一条路径 如此循环做法将所有的可能均遍历一遍 整个过程就是一直反复进行直到所有的节点被访问完为止且每个节点均只能访问一次
C++

详解:自定义dfs函数(函数体:首先使用if语句判断是否越界 使用if语句判断是否为终点坐标 使用if语句判断坐标是否有障碍或者是否已经过 三个if语句并列使用) 接下来的代码为均不符合三个if语句的条件 则执行的代码:
首先坐标未越界 未达终点 未经过 无障碍 不就只有一种可能 这是可能是一条可通的路径的某一步 那么现在占领此位置就需要把它标记为已经过 继而就是接着继续走下一步 上述题目已提及:可上下左右的移动 那么咋们就调用dfs()函数 让dfs()函数去给咋们寻找出口(接着上述所说的步骤循环调用dfs()函数 将移动上下左右后的坐标传入函数中 循环执行函数体中的代码 直至寻找到一条畅通无阻的道路)自定义结束后:在主函数的函数体中 按照题目要求 使用正确的格式正确地输入以及结束时的输出 利用for循环输入存在障碍的坐标 此时标记此位置存在障碍 以便在调用dfs函数时判断路径能否通过 此时有个特别特殊的情况 那便是终点存在障碍 辣么此时可用if语句来判断
前奏结束 此时调用dfs函数

#include <bits/stdc++.h>
using namespace std;
int n,m,ans,t,sx,sy,fx,fy,tx,ty;//分别定义为行数 列数 路径总数(输出的答案)障碍个数 起点以及终点的坐标 标记障碍时数组的下标
int a[5][5];//定义数组a用于存放迷宫中为位置的坐标
void dfs(int x,int y)
{
   if(x<1 || x>n || y<1 || y>m)//利用if语句判断是否越界
       return;
   if(x==fx && y==fy)//判断是否已到达终点
   {
       ans++;//自增
       return;
   }
   if(a[x][y]==1 || a[x][y]==2)//若此位置已经过或者存在障碍物
       return;
   a[x][y]=1;//若未执行上述的if语句 则说明此位置可通 标记成已经过
   dfs(x+1,y);//下
   dfs(x,y+1);//右
   dfs(x-1,y);//上
   dfs(x,y-1);//左
   a[x][y]=0;//清零
}
int main()//主函数
{
   cin>>n>>m>>t;
   cin>>sx>>sy>>fx>>fy;
   for(int i=0;i<t;i++)//利用for循环 输入存在障碍的位置即坐标 并标记为1
   {
       cin>>tx>>ty;
       a[tx][ty]=2;
   }
   if(a[fx][fy]==2)//终点存在障碍
   {
       cout<<"0";//输出零
       return 0;
   }
       dfs(sx,sy);//调用dfs函数
       cout<<ans;
   return 0;
}

emmm

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值