系列文章目录

文章目录

  • 系列文章目录
  • 前言
  • 一、题目描述
  • 二、c++代码
    • 1.使用栈
    • 2.递归
  • 总结

前言

八个方向的迷宫问题

一、题目描述

给定一个迷宫,左上角为入口,右下角为出口,求出行走路径。
一共八个方向:东、南、西、北、东北、东南、西北、西南,分别记为E S W N NE SE NW SW。

m*n的迷宫:

0 1 1 1 0 1 1 1
1 0 1 0 1 0 1 0
0 1 0 0 1 1 1 1
0 1 1 1 0 0 1 1
1 0 0 1 1 0 0 0
0 1 1 0 0 1 1 0

入口为左上角,出口为右下角。
有八个方向可以供选择。

上述0表示可走,1表示不可走。为方便处理,在迷宫周围加上一圈墙壁(即1、代表不可走),可省去边界检查。
之后得到一个(m+2)*(n+2)的迷宫,入口为(1,1),出口为(m,n)

1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 0 1 1 1 1
1 1 0 1 0 1 0 1 0 1
1 0 1 0 0 1 1 1 1 1
1 0 1 1 1 0 0 1 1 1
1 1 0 0 1 1 0 0 0 1
1 0 1 1 0 0 1 1 0 1
1 1 1 1 1 1 1 1 1 1

定义一个数组move表示移动方向,由0-7代表8个移动方向,每个方向都有垂直坐标和水平坐标。
搜索策略是先试探正北方向,然后顺时针试探其他方向

二、c++代码

1.使用栈

代码如下:

#include<iostream>
#include<stack>
using namespace std;typedef struct {int x;int y;
}point;int num_step = 0;                    //找到出口一共走了多少步
stack<point> result_path;            //用一个栈保存有效的路径(即从入口到出口的路径)int Maze[8][10]={{1,1,1,1,1,1,1,1,1,1},{1,0,1,1,1,0,1,1,1,1},{1,1,0,1,0,1,0,1,0,1},{1,0,1,0,0,1,1,1,1,1},{1,0,1,1,1,0,0,1,1,1},{1,1,0,0,1,1,0,0,0,1},{1,0,1,1,0,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};         //迷宫point mov[8] = { { -1, -1 },{ -1, 0 },{ -1, 1 },{ 0, -1 },{ 0, 1 },{ 1, -1 },{ 1, 0 },{ 1, 1 } };   //移动方向表,共8个方向,首先从正北开始 然后顺时针走其他方向bool MazePath(int row, int column, int x, int y){   //(1,1)为迷宫入口stack<point> process_path;      //用一个栈保存走过的路径bool flag;                      //是否存在一条从入口到出口的路径,如存在则flag为true,如不存在为falsepoint now;                      //设置当前所在位置为迷宫入口,即x,ynow.x = x;now.y = y;process_path.push(now);         //将当前位置添加到process_path中while (!process_path.empty()){now = process_path.top();        //取栈顶元素if (Maze[now.x][now.y] == 0){  //如果路可以走result_path.push(now);      //因为result_path为全局变量所以下面也用得到,画路径要用Maze[now.x][now.y] = -1;    //将有效路径的位置置为-1}flag = true;for (int i = 0; i<8; i++){      //一共8个方向可以走if (now.x + mov[i].x == row && now.y + mov[i].y == column)return true;           //到达终点.if (Maze[now.x + mov[i].x][now.y + mov[i].y] == 0){    //如果道路可通point temp;temp.x = now.x + mov[i].x;temp.y = now.y + mov[i].y;process_path.push(temp);flag = false;}}if (flag){process_path.pop();result_path.pop();}}return flag;
}void PrintPath(int row, int column){//输出从入口到出口的路径point temp;temp.x = row;temp.y = column;stack<point> pp;pp.push(temp);while (!result_path.empty()){temp = result_path.top();result_path.pop();pp.push(temp);}while (!pp.empty()){temp = pp.top();cout << '(' << temp.x << ',' << temp.y << ')' << ' ';num_step++;pp.pop();}cout << endl;cout <<"最短路径为:"<< num_step <<"步"<<endl;
}
int main(){int row=6, column=8;if (MazePath(row, column, 1, 1)){cout << "YES" << endl;PrintPath(row, column);}else cout << "NO" << endl;return 0;
}

以上方法将有效路径的迷宫位置 置为-1,还有一种方式是另外设置一个矩阵Mark,用来标记有效路径,初始化为全零,有效位置 置1

#include<iostream>
#include<stack>
using namespace std;typedef struct {int x;int y;
}point;int num_step = 0;                    //找到出口一共走了多少步
stack<point> result_path;            //用一个栈保存有效的路径(即从入口到出口的路径)int Maze[8][10]={{1,1,1,1,1,1,1,1,1,1},{1,0,1,1,1,0,1,1,1,1},{1,1,0,1,0,1,0,1,0,1},{1,0,1,0,0,1,1,1,1,1},{1,0,1,1,1,0,0,1,1,1},{1,1,0,0,1,1,0,0,0,1},{1,0,1,1,0,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};         //迷宫int Mark[8][10] = {0};                  //将标记矩阵初始化为全零point mov[8] = { { -1, -1 },{ -1, 0 },{ -1, 1 },{ 0, -1 },{ 0, 1 },{ 1, -1 },{ 1, 0 },{ 1, 1 } };   //移动方向表,共8个方向,首先从正北开始 然后顺时针走其他方向bool MazePath(int row, int column, int x, int y){     //(1,1)为迷宫入口stack<point> process_path;      //用一个栈保存走过的路径bool flag;                      //是否存在一条从入口到出口的路径,如存在则flag为true,如不存在为falsepoint now;                      //设置当前所在位置为迷宫入口,即x,ynow.x = x;now.y = y;process_path.push(now);         //将当前位置添加到process_path中while (!process_path.empty()){now = process_path.top();        //取栈顶元素if (Maze[now.x][now.y] == 0 && Mark[now.x][now.y] == 0){ //如果路可以走result_path.push(now);      //因为result_path为全局变量所以下面也用得到,画路径要用Mark[now.x][now.y] = 1;}flag = true;for (int i = 0; i<8; i++){      //一共8个方向可以走if (now.x + mov[i].x == row && now.y + mov[i].y == column)return true;          //到达终点.if (Maze[now.x + mov[i].x][now.y + mov[i].y] == 0 && Mark[now.x + mov[i].x][now.y + mov[i].y] == 0){       //如果道路可通point temp;temp.x = now.x + mov[i].x;temp.y = now.y + mov[i].y;process_path.push(temp);flag = false;}}if (flag){process_path.pop();result_path.pop();}}return flag;
}void PrintPath(int row, int column){//输出从入口到出口的路径point temp;temp.x = row;temp.y = column;stack<point> pp;pp.push(temp);while (!result_path.empty()){temp = result_path.top();result_path.pop();pp.push(temp);}while (!pp.empty()){temp = pp.top();cout << '(' << temp.x << ',' << temp.y << ')' << ' ';num_step++;pp.pop();}cout << endl;cout <<"最短路径为:"<< num_step <<"步"<<endl;
}
int main(){int row=6, column=8;if (MazePath(row, column, 1, 1)){cout << "YES" << endl;PrintPath(row, column);}else cout << "NO" << endl;return 0;
}

2.递归

代码如下:

#include<iostream>
#include<stack>
using namespace std;typedef struct {int x;int y;
}point;int num_step = 0;                    //找到出口一共走了多少步
stack<point> result_path;            //用一个栈保存有效的路径(即从入口到出口的路径)int Maze[8][10]={{1,1,1,1,1,1,1,1,1,1},{1,0,1,1,1,0,1,1,1,1},{1,1,0,1,0,1,0,1,0,1},{1,0,1,0,0,1,1,1,1,1},{1,0,1,1,1,0,0,1,1,1},{1,1,0,0,1,1,0,0,0,1},{1,0,1,1,0,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};         //迷宫point mov[8] = { { -1, -1 },{ -1, 0 },{ -1, 1 },{ 0, -1 },{ 0, 1 },{ 1, -1 },{ 1, 0 },{ 1, 1 } };   //移动方向表,共8个方向,首先从正北开始 然后顺时针走其他方向bool MazePath(int row, int column, int x, int y){   //递归point temp;temp.x = x;temp.y = y;Maze[x][y] = -1;result_path.push(temp);for(int i=0;i<8;i++){if(x+mov[i].x == row && y+mov[i].y == column)return true;if(Maze[x+mov[i].x][y+mov[i].y] == 0){if(MazePath(row,column,x+mov[i].x,y+mov[i].y))return true;}}result_path.pop();return false;
}void PrintPath(int row, int column){//输出从入口到出口的路径point temp;temp.x = row;temp.y = column;stack<point> pp;pp.push(temp);while (!result_path.empty()){temp = result_path.top();result_path.pop();pp.push(temp);}while (!pp.empty()){temp = pp.top();cout << '(' << temp.x << ',' << temp.y << ')' << ' ';num_step++;pp.pop();}cout << endl;cout <<"最短路径为:"<< num_step <<"步"<<endl;
}
int main(){int row=6, column=8;if (MazePath(row, column, 1, 1)){cout << "YES" << endl;PrintPath(row, column);}else cout << "NO" << endl;return 0;
}

总结

迷宫问题(八方向)c++相关推荐

  1. 【手把手带你学JavaSE】(项目展示)老鼠走迷宫和八皇后问题

    目录 前言 老鼠走迷宫 MiGong.java 八皇后问题 Queen.java 前言 大家还记得当初C语言我们一起学习的递归吗?说好的要实现老鼠走迷宫和八皇后问题!他来了!!! 老鼠走迷宫 MiGo ...

  2. Silverlight C# 游戏开发:方向键的组合,八方向实现

    Silverlight C# 游戏开发:方向键的组合,八方向实现 在游戏中,有一种情况是斜向移动,就是同时按下两个方向,形成斜线操作,在Win32GDI开发中,可以通过在逻辑循环里加入键盘状态判断取得 ...

  3. python实现基于八方向判断的断裂连接

    ''' 八方向连接算法 ''' import numpy as np import matplotlib.image as mpimg from PIL import Image def comput ...

  4. 【Cocos2d-Js实战教学(1)横版摇杆八方向移动】

    本教程主要通过搭建一个横版摇杆八方向移动的实例,让大家如何用Cocos2dx-Js来做一款 游戏,从基础了解Cocos2dx-Js的基本实现原理,从创建工程,到各个知识点的梳理. 教程分为上下两讲: ...

  5. 手游摇杆(二)八方向摇杆和移动范围限制

    手游摇杆: (零)摇杆设计原理 (一)最简单的四方向摇杆 (二)八方向摇杆和移动范围限制 (三)跟随式摇杆 前面的实现了一版最简单的四方向摇杆,基于此做两个方面的优化: 升级为八方向 限制移动范围 一 ...

  6. css绘制八方向云台 环形按钮盘

    翻了很多帖子,最终基于https://blog.csdn.net/zhangtff/article/details/89458797的文章,使用css绘制出八方向用来控制摄像机等的按钮盘,于此记录. ...

  7. 在CIELab颜色空间下使用八方向Sobel算子实现边缘检测

    参考河北师范大学硕士学位论文--基于八方向Sobel算子的边缘检测算法研究. 由于自己实现滤波器运算,计算速度很慢,以后有能力再进行改进. 算子定义如下: 算法思路: 1.将RGB图像转化为CIELa ...

  8. 矢量线八方向和全方向栅格化算法C#实现

    文章目录 引言 1算法 1.1矢量点的栅格化 1.1.1思想 1.1.2算法实现 1.2矢量线的栅格化 1.2.1八方向栅格化 思想 算法流程 算法实现 1.2.2 全路径矢量化 思想 算法流程 算法 ...

  9. 【边缘检测】基于matlab八方向sobel图像边缘检测【含Matlab源码 1865期】

    ⛄一.八方向Sobel算子的边缘检测算法简介 1 引言 随着数字图像的广泛应用, 对图像精度的要求也逐步提高.边缘是目标图像与背景图像的分界, 是图像最基本的特征之一.图像边缘蕴含了图像丰富的内在信息 ...

  10. PhotoShop算法实现进阶-浮雕滤镜-八方向浮雕(三十)

    PhotoShop算法实现进阶-浮雕滤镜-八方向浮雕(三十) kezunhai@gmail.com http://blog.csdn.net/kezunhai 八方向浮雕根据不同的雕刻方向,产生不同方 ...

最新文章

  1. dede自定义表单增加添加时间怎么弄
  2. ITK:多路输出不同的类型
  3. 常见视频接口介绍,VGA,YPbPr,DVI,HDMI,DisplayPort
  4. android动画效果 --- 设置activity 跳转动画
  5. java中对时间的操作
  6. 系统分析师资料_软考 系统分析师考试通过总结
  7. java拷贝构造函数
  8. 免费素材下载:一套超棒的免费UI套件
  9. python程序设计陈春晖答案_Python程序设计
  10. openWRT提示JFFS2-partition seems full
  11. Bypassing Stack Cookies, SafeSeh, SEHOP, HW DEP and ASLR
  12. 南郭先生不一样得解读
  13. 什么是铠装光纤跳线及它的特点?
  14. 网易2011笔试题详解
  15. 用VHDL编写testbench激励文件
  16. 2020年2月15日 考试【更新中】
  17. ubuntu 百度云盘
  18. fluent二维叶型仿真_Hitalk—长沙理工大学机械软件仿真作品设计大赛
  19. symfony学习笔记1—简介
  20. 常见的网络安全设备及功能汇总

热门文章

  1. Ubuntu零基础教学-SpringBoot项目如何生成SSL证书并配置HTTPS协议 | 超级详细,建议收藏
  2. 替尼泊苷多层包衣白蛋白纳米粒/人血清白蛋白-聚己内酯纳米的制备
  3. 保存的视频如何去掉水印
  4. Python每日一练(24)-requests 模块获取免费的代理并检测代理 IP 是否有效
  5. 使用Charles抓包安卓模拟器(MuMu)
  6. 电脑奔溃的时候,到底发生了什么?
  7. linux 软raid恢复,Linux软RAID部署系统分区之恢复攻略
  8. 解决:matplotlib画图时,横坐标日期太多重叠在一起,减少横坐标数量
  9. 【Adobe After Effects中英文转换2019——2023版】
  10. 修改主机Host配置(可用于屏蔽网站/广告、防止DNS劫持和污染)