迷宫地形我们可以通过读文件的形式,通过已知入口逐个遍历坐标寻找通路。

文件如图:

每个坐标的位置用结构体来记录:

struct Pos    //位置坐标
{
int _row;
int _col;
};

 定义行列范围:

#define M 10   //行
#define N 10 //列

初始化迷宫数组
将通过读文件的方式获取的字符转成整型数据,保存在M行N列的数组中。

void InitMaze(int* maze)
{
struct WavHeadhWAV;
FILE* fout = fopen("MazeMap.txt", "r"); // .txt文件要放在当前目录下
if (fout == NULL) // 这里一定要检查读文件是否成功
{
cout << "can't find MazeMap.txt !" << endl<<endl;
return;
}
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N;)
{
char ch = fgetc(fout);
if (ch=='1'||ch=='0')
{
maze[i*N + j] = ch - '0';
j++;
}
}
}
fclose(fout);
}

回溯查找通路

利用栈来存储通路,通过上下左右四个方向依次遍历,如果该位置满足条件,就将它入栈,并将该位置的数据置为2;如果四个方向都不满足条件就执行出栈操作,回溯查找满足条件的位置(这时候如果栈为空了,说明查找通路失败),继续循环遍历,直到找到出口为止。

这里建立一个最小栈,如果找到出路,就将该栈赋给最小栈,并将出口置为1,继续回溯查找通路,如果又一次找到通路,就将该栈的长度与最小栈进行比较,如果该栈长度比最小栈还要小,就将它再一次赋给最小栈(保证最小栈是最短的通路),继续回溯,直到整个栈为空,回到了入口,程序结束。

bool SearchMazePath(int *maze, Pos entry, stack<Pos>& paths)   // 利用栈回溯查找通路,并实现迷宫的最优解
{
assert(maze);
stack<Pos>min;
paths.push(entry);
while (!paths.empty())
{
Pos cur = paths.top();
maze[cur._row*N+cur._col] = 2;
if (cur._row==M-1)
{
if (paths.size()< min.size() || min.size() == 0)
{
min = paths;
}
paths.pop();
maze[min.top()._row*N + min.top()._col] = 1;
}
Pos next = cur;
next._col--; //左
if (CheckIsAccess(maze, next))
{
paths.push(next);
maze[next._row*N + next._col] = 2;
continue;
}
next = cur;
next._col++; //右
if (CheckIsAccess(maze, next))
{
paths.push(next);
maze[next._row*N + next._col] = 2;
continue;
}
next = cur;
next._row--; //上
if (CheckIsAccess(maze, next))
{
paths.push(next);
maze[next._row*N + next._col] = 2;
continue;
}
next = cur;
next._row++; //下
if (CheckIsAccess(maze, next))
{
paths.push(next);
maze[next._row*N + next._col] = 2;
continue;
}
paths.pop();
}
if (paths.empty()&&!min.empty())
{
maze[min.top()._row*N + min.top()._col] = 2;
return true;
}
return false;
}

  检查该位置是否合法:(坐标在行列范围之内)

bool CheckIsAccess(int* maze, const Pos& next)    // 检查该位置是否合法
{
assert(maze);
if ((next._row >= 0 && next._row <= N) && (next._col >= 0 && next._col < M) && maze[next._row*N + next._col] == 0)
{
return true;
}
return false;
}

  打印迷宫:

void PrintMaze(int *maze)   // 打印迷宫
{
assert(maze);
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
cout << maze[i*N + j] <<" " ;
}
cout << endl;
}
cout << endl;
}

  

Maze迷宫问题(求最优解)的更多相关文章

  1. 【南京邮电】maze 迷宫解法

    [南京邮电]maze 迷宫解法 题目来源:南京邮电大学网络攻防训练平台. 题目下载地址:https://pan.baidu.com/s/1i5gLzIt (密码rijss) 0x0 初步分析 题目中给 ...

  2. [LeetCode] The Maze 迷宫

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  3. hdu4035 Maze (树上dp求期望)

    dp求期望的题. 题意: 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结点i都有3种可能: 1.被杀死,回到结点1处(概率为ki) 2.找到出口,走出迷宫 ...

  4. [LeetCode] 490. The Maze 迷宫

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  5. 利用C语言判定用户输入数据从而给出结果(利用判定用户体重范围)同求最优解!!!

    例子: 要求:医务工作者通过广泛的调查和统计分析,根据成人的身高与体重因素给出了按"体质指数"进行判断的方法,具体如下: 体质指数t=体重 w/(身高h)2(w的单位为kg,h的单 ...

  6. Lagrange 乘子法求最优解

    clc clear syms x y z r1 r2 w f=x^+y^+z^+w^; g1=*x-y+z-w-; g2=x+y-z+w-; h=f-r1*g1 -r2*g2; hx=diff(h,x ...

  7. Atcoder Beginner Contest151D(迷宫问题求任意两点最短路径的最大值,BFS)

    BFS可以求得最短路,DFS会找到从当前点到图中叶子结点的路径. #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using na ...

  8. 石子合并2(环形求最优解 区间dp)

    题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...

  9. [LeetCode] 499. The Maze III 迷宫 III

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

随机推荐

  1. 百度js 获取定位城市名称

    首先引用百度 script <script type="text/javascript" src="http://api.map.baidu.com/api?typ ...

  2. PS 流格式解析(转)

    对于PS流,最近因为工作需要,所以MPEG2中的PS流格式和解包过程进行了学习. 首先我们需要知道PS包流格式是怎么样的: 针对H264 做如下PS 封装:每个IDR NALU 前一般都会包含SPS. ...

  3. ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪

    ASP.NET MVC深入浅出(被替换)   一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...

  4. Java 多线程 并发编程 (转)

    一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种 ...

  5. Spring Boot从入门到实战:整合通用Mapper简化单表操作

    数据库访问是web应用必不可少的部分.现今最常用的数据库ORM框架有Hibernate与Mybatis,Hibernate貌似在传统IT企业用的较多,而Mybatis则在互联网企业应用较多.通用Map ...

  6. Hadoop MapReduce八大步骤以及Yarn工作原理详解

    Hadoop是市面上使用最多的大数据分布式文件存储系统和分布式处理系统, 其中分为两大块分别是hdfs和MapReduce, hdfs是分布式文件存储系统, 借鉴了Google的GFS论文. MapR ...

  7. cordova ios升级插件

    org.ssgroup.sope.cordova.upgrade 支持强制升级与选择升级 插件已经开源在https://github.com/shenshouer/org.ssgroup.sope.c ...

  8. keil中使用Astyle格式化你的代码的方法2篇合

    关于Astyle Astyle 的全称是Artistic Style的简称,是一个开源的源代码格式化工具,可以对C,C++,C#以及Java等编程语言的源代码进行缩进.格式化.美化.Home Page ...

  9. 使用 SourceTree 遇到冲突的解决方法

    首先,更新代码之前先 git stash ,然后 git pull ,再 git stash pop 这时候如果本地改的代码跟线上的冲突了,就报错了.那么就需要手动解决冲突. 打开存在冲突的文件,会看 ...

  10. WPF 员工卡条形码

    大家都知道条形码(Barcode)是一种可以由机器识别的特殊编码,在生产.生活中也常常会见到并使用它.条形码的类型和种类很多感兴趣的朋友可以详细了解一下.其中Code 39 可以说是一种最为常见并广泛 ...