Exp02 迷宫的求解

Author: Maskros

实验目的

输入迷宫,得到从入口到出口的(最短)路径

实验内容与要求

迷宫只有两个门,一个叫做入口,另一个叫做出口。把一只老鼠从一个无顶盖的大盒子的入口处赶进迷宫。迷宫中设置很多隔壁,对前进方向形成了多处障碍,在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口。求解迷宫问题,即找出从入口到出口的路径。

实验内容和实验步骤

分别通过深度优先搜索 (dfs) 和广度优先搜索 (bfs) 两种方法来实现实验要求

  • 大体思路:

    • dfs O(m∗n)O(m*n)O(m∗n)?:

      • 结构体point 存储点的信息,maze[][]存图,visit[][]判断是否访问过,dir[4][2]用于存储四个方向,便于查找
      • stack<point> s 栈用于存储最终路径
      • void dfs(int x,int y) 函数对坐标进行深度优先搜索,采用递归的思路,顺着一条路猛找,找不到返回上一级结点,直到找到为止。
      • void printpoint() 函数用于打印路径
      • void printmaze() 函数用于打印地图
    • bfs O(m+n)O(m+n)O(m+n)?:
      • 结构体node 存储点的信息,其中int l 表示从开始到该结点的距离,node father[][]数组用于存储当前节点的上一步是哪个结点,便于输出路径,其余变量同dfs
      • queue<node> q 用于读入可走的路径,在bfs中使用
      • bool check(int x,int y) 函数用于判断当前结点是否可走
      • int bfs(node s) 函数,结束标志为队空,从当前结点依次遍历可走的方向,如果可以继续走就将可走结点入队,如果走到终点即返回最短路径长度
      • string to_string(int s) 函数用于将int类型转为string类型,便于输出路径
      • void print()函数根据father[][]从终点逆推打印路径
  • 输入形式:首先输出两个正整数 mmm , nnn , 表示迷宫的有 nnn 行 mmm 列,接下来输入迷宫序列, 1 表示可以通过, 0 表示不能通过。
  • 输出形式:以 bfs 实现的为例,首先输出最短路长度 lminl_{min}lmin​ , 接下来以 (xi,xi)(x_i,x_i)(xi​,xi​) -> $(x_j,y_j) $ … 表示这条路径,最后输出地图,用* 表示走过的路使结果更加直观;没有路径则输出-1

dfs实现(求一条路径)

//presented by Maskros - 2021/04/21
//dfs
#include<bits/stdc++.h>
using namespace std;
int m,n;
char maze[20][20];  //map
int vis[20][20]={0};   //check if visited
int dir[4][2]={        //four directrions{0,-1},{-1,0},{0,1},{1,0}
};
char ans[20][20];
struct point{   int x,y;    //coordinatechar d;     //Record directionpoint(){};point(int a,int b,char c):x(a),y(b),d(c){}
}pp;
char check(int x,int xx,int y,int yy){  //Check the direction of the pathif(xx>x) return 'D';if(xx<x) return 'U';if(yy>y) return 'R';if(yy<y) return 'L';return '\0';
}
bool ed=false;
stack <point> s;
void dfs(int x,int y){  //Depth first searchif(x>=m||x<0||y>=n||y<0) return ; //Can't reachif(x==m-1&&y==n-1) {ed=true; return ;}   //reach destinationint nx,ny;for(int i=0;i<4;i++){nx=x+dir[i][0];ny=y+dir[i][1];if((nx<m&&nx>=0&&ny<n&&ny>=0) && vis[nx][ny]==0 && maze[nx][ny]=='1'){vis[nx][ny]=1;dfs(nx,ny);if(ed==true){ s.push(point(nx,ny,check(x,nx,y,ny))); return ; } //Recursive search the path}}
}
void printpoint(){  //Print pathputchar('\n');char dd;bool st=false;while(!s.empty()){pp=s.top();s.pop();if(st) {dd=pp.d; cout<<dd<<")"<<endl;}else st=true;ans[pp.x][pp.y]='*';if(pp.x==m-1 && pp.y==n-1) dd='E';cout<<"("<<pp.y+1<<","<<pp.x+1<<",";}cout<<dd<<")"<<endl;return ;
}
void printmaze(){   //Print mapcout<<endl;for(int i=0;i<m;i++){for(int j=0;j<n;j++){cout<<ans[i][j]<<" ";}cout<<endl;}return;
}
int main(){cin>>m>>n;for(int i=0;i<m;i++)for(int j=0;j<n;j++){cin>>maze[i][j];ans[i][j]=maze[i][j];}if(maze[0][0]=='0'||m==0||n==0||maze[m-1][n-1]=='0'){cout<<"no way";return 0;} else {ans[0][0]='*';vis[0][0]=1;} dfs(0,0);if(ed==false) {cout<<"no way"<<endl; return 0;}else s.push(point(0,0,'\0'));printpoint();printmaze();return 0;
}

bfs实现(求最短路)

//presented by Maskros - 2021/04/21
//bfs
#include<bits/stdc++.h>
using namespace std;
int m,n;
char maze[20][20];  //map
int vis[20][20]={0};   //check if visited
struct node{int x,y;    //coordinateint l;      //Path lengthnode(){}node(int a, int b):x(a),y(b),l(0){}node(int a, int b, int ll):x(a),y(b),l(ll){}
};
node father[20][20];    //The previous node of the current node in the path
queue<node> q;    int dir[4][2]={        //four directions{0,-1},{-1,0},{0,1},{1,0}
};
bool check(int x,int y){    //Judge if can goif(x>=0 && x<m && y>=0 && y<n && vis[x][y]==0 && maze[x][y]=='1')return true;else return false;
}int bfs(node s){   //Breadth first search, based on queueint nx,ny;q.push(s);vis[s.x][s.y]=1;node tmp,next;while(!q.empty()){tmp=q.front();q.pop();if(tmp.x==m-1&&tmp.y==n-1)  return tmp.l; //reach destinationfor(int i=0;i<4;i++){  //Look in four directions in turnnx=tmp.x+dir[i][0];ny=tmp.y+dir[i][1];if(check(nx,ny)) {next=node(nx,ny,tmp.l+1);father[nx][ny]=node(tmp.x,tmp.y);  //Record the previous nodeq.push(next);vis[nx][ny]=1;}}}return -1;
}
string to_string(int s){    //Convert int to string and save in the pathstring l;while(s){int tmp=s%10;l=char(tmp+'0')+l;s/=10;}return l;
}
void print(){       //Print path and mapstring s="("+to_string(m)+","+to_string(n)+")";node tt=father[m-1][n-1];maze[m-1][n-1]='*';while(1){s="("+to_string(tt.x+1)+","+to_string(tt.y+1)+") -> "+s;maze[tt.x][tt.y]='*';if(tt.x==0 && tt.y==0) break;tt=father[tt.x][tt.y];}cout<<s<<endl<<endl;for(int i=0;i<m;i++){for(int j=0;j<n;j++){cout<<maze[i][j]<<" ";}cout<<endl;}return ;
}
int main(){cin>>m>>n;for(int i=0;i<m;i++){for(int j=0;j<n;j++){cin>>maze[i][j];}}if(!check(0,0)){ cout<<-1; return 0;}  //Special caseint lmin=bfs(node(0,0)); //Shortest path lengthif(lmin==-1) cout<<-1;else {cout<<endl;cout<<"The length of the way is: "<<lmin<<endl;print();}return 0;
}

实验用测试数据和相关结果分析

Test 1
5 5
1 1 1 1 1
0 0 0 0 1
1 1 1 1 1
1 0 0 0 0
1 1 1 1 1Test 2
1 1
1Test 3
1 5
1 1 0 1 1Test 4
4 4
1 1 1 0
1 0 1 1
1 1 1 0
1 0 0 1Test 5
9 7
1 1 1 1 1 1 1
0 0 0 0 0 0 1
1 1 1 1 1 1 1
1 0 1 0 0 0 0
1 1 1 1 1 1 1
0 0 0 0 1 0 1
1 0 1 1 1 1 1
1 0 1 0 1 0 1
1 0 1 1 1 0 1

  • 结果分析:无论是起点终点重合,没有通路,以及对最短路的寻找均有正确的输出

实验总结

  • 分别温习了栈和队列的使用,基于栈通过dfs递归爆搜出一条通路,以及基于队列通过bfs逐渐找到一条最短路径
  • 干,时间复杂度有点不会算
  • dfs 和 bfs 典中典,stl yyds

数据结构实验二:迷宫的求解相关推荐

  1. 数据结构实验二 :二叉树的操作与实现

    数据结构实验一:线性表,堆栈和队列实现 数据结构实验二 :二叉树的操作与实现 数据结构实验三: 图的操作与实现 数据结构实验四 : 查找和排序算法实现 文章目录 一.实验目的: 二.使用仪器.器材 三 ...

  2. 数据结构实验二 树和二叉树的实现

    广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A)     2019年5月13日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 学号 17061 ...

  3. 数据结构-实验二  树和二叉树的实现

     广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼417)     2018年05月16日 学院 计算机科学与教育软件学院 年级.专业.班 网络161 姓名 卟咚君 学号 1606100 ...

  4. 南京邮电大学数据结构实验二(代码篇)

    文章目录 一.二叉树的创建和遍历 二.二叉树求解 三.哈夫曼树 一.二叉树的创建和遍历 #include<stdio.h> #include<stdlib.h> #define ...

  5. 线性表基本操作,单链表的建立(头插法,尾插法)、插入、删除、遍历操作的实现(c++ 数据结构 实验二)

    大学数据结构课程的实验题目,掌握线性表的链接存储结构,用c++语言描述 一.实验要求 1.分别用头插法和尾插法建立一个含有若干结点的单链表 2.对已建立的单链表进行插入.删除.遍历输出等操作 二.代码 ...

  6. 算法设计与分析 实验二 分治法求解最近点对问题

    分治法求解最近点对问题 一.实验目的与要求 1.实验基本要求 2.实验亮点 二.实验内容与方法 三.实验步骤与过程 (一)一些准备工作 1.实验流程 2.数据生成与去除重复点 (二)暴力穷举法 1.算 ...

  7. 穿越迷宫c语言程序设计教程课后答案,实验二 迷宫实验.doc

    #include #define ROW 11 #define COLUMN 15 typedef struct { /*栈中的数据元素的类型定义*/ int row; /*行下标*/ int col ...

  8. 数据结构实验二——队列(银行叫号系统)

    一.实验目的 (1)掌握队列的链式存储结构 (2)掌握队列的基本操作,并能进行应用实践 (3)使用C/C++语言和队列实现"银行叫号系统"专题 二.实验任务 设计一个控制台程序,模 ...

  9. 人工智能实验二——prolog语言求解渡河问题(传教士和野人渡河,农夫渡河问题)实现详解

    农夫渡河问题求解 这两个问题都是渡河问题,思路和方式是一样的:给出求解Prolog代码: 问题描述 一个农夫带着一匹狼.一只羊.一颗白菜要过河, 只有一条船而且 农夫每次最多只能带一个动物或物品过河, ...

最新文章

  1. 第三章 Java Servlet基础
  2. POJ C程序设计进阶 编程题#3:运算符判定
  3. TF之DCGAN:基于TF利用DCGAN测试自己的数据集并进行生成过程全记录
  4. ingress controller 和ingress使用实例
  5. Hystrix---SpringCloud
  6. Apache Ignite本机持久性,简要概述
  7. uni-app微信小程序获取手机号;微信小程序获取手机号,获取到后需要进行解密;微信小程序获取手机号失败 Error:该appId没有权限
  8. 面向对象的JavaScript框架 MooTools
  9. 新蓝剑java_Ubuntu 8.10 编译安装飞鸽(IPMsg 0.9.6)
  10. 家境一般但被中外合资大学录取了,现在家庭气氛紧张
  11. 企业信息化政务信息化浙里办
  12. UDP测试工具(ace版本)
  13. dubbo源码解析-directory
  14. 绝对靠谱安全的论文免费安全查重检测重复率网站
  15. 论mybatisPlus 连表插件(MPJBaseMapper) 与自定义SQL注入器冲突
  16. 设随机过程{X(t)=Acos(ωt+Θ),t∈(一∞,+∞)},其中A,ω,Θ为相互独立的实随机变量,其中A的均值为2,方差为4,且Θ~U(-π,π),ω~U(-5,5),试问X(t)是否为平稳过程
  17. netcore读取json文件_.Net Core读取Json配置文件的实现示例
  18. 你需要了解的JS框架
  19. gstreamer(三) 常用命令集锦
  20. 针对尚硅谷教学微服务硅谷课堂在线学习平台的部分功能的自我改进

热门文章

  1. SpringMVC的数据响应-回写数据-返回对象或集合2(应用)
  2. 使用JWT进行跨域身份验证
  3. 多值参数-定义及作用
  4. plsql(轻量版)_基本语法
  5. Linux下Mysql设置外网可以访问
  6. fedora yum mysql_Fedora14使用yum安装mysql
  7. Maven(2)--生命周期以及插件目标
  8. 计算机与人力资源管理论文,人力资源管理专业计算机能力培养模式论文
  9. 【报错笔记】做struts项目建立jsp文件老是报错
  10. 增加关系型数据库驱动配置同步任务