- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
参考上图所示迷宫,编写算法求一条从入口到出口的有效路径.
通常采用穷举法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路返回,换另一个方向继续探索,直到探索到出口为止。 为了保证在任何位置都能原路返回,显然需要用一个先进后出的栈来保存从入口到当前位置的路径.
求迷宫中一条路径的算法的基本思路是:
如果当前位置“可通”,则纳入“当前路径”,并继续朝下一个位置探索,即切换下一个位置为当前位置,如此重复直至到达出口;如果当前位置不可通,则应沿“来向”退回到前一通道块,然后朝“来向”之外的其他方向继续探索;如果该通道块的四周4个方块均不可通,则应从当前路径上删除该通道块。 所谓下一位置指的是当前位置四周(东、南、西、北)4个方向上相邻的方块。 ** 。
1.声明一个结构体patch表示每一个方块,含有两个成员:
(1)int type: 1-通道;0-墙; (2)int flag: 1-未走;0-已走;-1-不可走.
2.创建一个矩阵表示迷宫,元素类型为结构体patch.
3.创建一个栈,用于存储当前路径依次所经过的每个patch的坐标信息(x, y).
4.从当前位置cur出发(cur初始化为起点位置),然后基于cur按“东-南-西-北”4个方向顺序依次试探,即按选定的试探方向往前进一个patch到达next位置:
(1)若next“可走”,则将cur入栈,同时将cur对应patch的flag更新为0,然后将cur更新为next,然后重复4; (2)若next“不可走”,则改变试探方向基于cur前进一个patch获取新next,然后重复(1); (3)若cur的“东-南-西-北”4个方向均“不可走”,则代表当前位置cur对应patch不可通,将cur对应patch的flag设为-1,执行出栈操作,并将cur更新为出栈元素对应的位置,将新cur对应patch的flag更新为1,然后重复4。 (4)若next等于终点,则将cur和next均入栈并将二者对应patch的flag更新为0,寻找有效路径结束。 (5)寻找过程中,若当前位置cur重新回退至起点位置,代表所给迷宫无解.
5.栈内存储的从“栈底元素 - 栈顶元素”对应的patch序列即为有效路径.
#include <iostream>
using namespace std;
#define MaxMazeSize 40 /* 迷宫的最大行列*/
#define MaxStackSize 100 /*栈的最大容量*/
/*声明一个结构体表示patch的坐标信息*/
typedef struct
{
int x, y;
} Position;
/* 声明一个结构体patch表示每一个方块 */
typedef struct
{
int type = 0; // 0-墙;1-通道
int flag = 1; // 0-已走;1-未走(可走);-1-不可走(禁走)
} Patch;
/*声明栈结构体*/
typedef struct
{
Position data[MaxStackSize];
Position *top = data; // 默认初始化栈
} PosStack;
PosStack S; // 创建栈保存有效路径坐标信息
Patch maze[MaxMazeSize][MaxMazeSize]; // 创建迷宫(二维列表):元素类型为结构体patch
int rows, cols; // 迷宫的行数及列数
Position startPos, endPos; // 起点坐标 + 终点坐标
/*初始化迷宫*/
void InitMaze()
{
int walls;
cout << "Please enter the number of rows and columns in the maze (separated by spaces): ";
cin >> rows >> cols;
int k = 0;
while (k < cols) // 设置迷宫外墙
{
maze[0][k].type = 0;
maze[0][k].flag = -1;
maze[rows - 1][k].type = 0;
maze[rows - 1][k].flag = -1;
k++;
}
k = 0;
while (k < rows) // // 设置迷宫外墙
{
maze[k][0].type = 0;
maze[k][0].flag = -1;
maze[k][cols - 1].type = 0;
maze[k][cols - 1].flag = -1;
k++;
}
for (int i = 1; i < rows - 1; i++) // 内部区域全部初始化为通道
{
for (int j = 1; j < cols - 1; j++)
{
maze[i][j].type = 1;
maze[i][j].flag = 1;
}
}
cout << "Please enter the number of walls in the maze: ";
cin >> walls; // 用户自定义设置内部区域墙的数量
cout << "Enter the coordinates of each wall (x and y are separated by spaces):\n";
int x, y;
for (int i = 0; i < walls; i++) // 用户自定义设置内部区域墙的位置
{
cin >> x >> y;
maze[x][y].type = 0;
maze[x][y].flag = -1;
}
}
/*展示迷宫结构*/
void DisplayMaze(int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "\t" << maze[i][j].type;
}
cout << endl;
}
}
/*给定坐标,判断该坐标对应patch是否可走*/
bool JudgeNext(Position next)
{
if (next.x < 0 && next.y > rows - 1)
{ // 判断该坐标是否越界
return false;
}
if (maze[next.y][next.x].type == 0)
{ // 判断该坐标对应patch是墙还是通道
return false;
}
if (maze[next.y][next.x].flag <= 0)
{ // 判断该坐标对应patch是否可走
return false;
}
return true;
}
/*迷宫求解*/
bool FindMazePath()
{
bool reFlag = false;
Position curPos = startPos; // 当前位置
Position nextPos; // 下一试探位置
int direction;
while (1)
{
direction = 1;
while (direction <= 4)
{
if (direction == 1) // 东
{
nextPos.x = curPos.x + 1;
nextPos.y = curPos.y;
}
else if (direction == 2) // 南
{
nextPos.x = curPos.x;
nextPos.y = curPos.y + 1;
}
else if (direction == 3) // 西
{
nextPos.x = curPos.x - 1;
nextPos.y = curPos.y;
}
else // 北
{
nextPos.x = curPos.x;
nextPos.y = curPos.y - 1;
}
if((nextPos.x == endPos.x) && (nextPos.y == endPos.y)){ // 抵达终点
*(S.top++) = curPos;
*(S.top++) = nextPos;
maze[curPos.y][curPos.x].flag = 0;
maze[nextPos.y][nextPos.x].flag = 0;
reFlag = true;
break;
}
if (JudgeNext(nextPos)){
break;
}else{
direction++; // 准备尝试下一试探方向
}
}
if (direction > 4) // 当前位置不可通
{
maze[curPos.y][curPos.x].flag = -1;
curPos = *(--S.top); // 执行出栈操作,并将当前位置更新为出栈patch对应位置
maze[curPos.y][curPos.x].flag = 1;
}else{ // next可走
*(S.top++) = curPos;
maze[curPos.y][curPos.x].flag = 0;
curPos = nextPos;
}
if(reFlag){
break; // 抵达终点,找到有效路径,终止寻找
}
if((curPos.x == startPos.x) && (curPos.y == startPos.y)){
cout << "Maze without a solution!\n";
break;
}
}
return reFlag;
}
int main()
{
InitMaze();
cout << "The maze is structured as follows:\n";
DisplayMaze(rows, cols);
cout << "Please enter the coordinates of the starting point (x and y are separated by spaces): ";
cin >> startPos.x >> startPos.y;
cout << "Please enter the coordinates of the end point (x and y are separated by spaces): ";
cin >> endPos.x >> endPos.y;
if(FindMazePath()){
cout << "Successfully found an effective path, as shown below:\n";
int length = S.top - S.data;
Position tmp;
for(int i = 0; i< length; i++){
tmp = *(--S.top);
maze[tmp.y][tmp.x].type = length - i;
}
DisplayMaze(rows, cols);
}else{
cout << "Failed to find a effective path!\n";
}
system("pause");
return 0;
}
case1 : 迷宫有解 。
case2 : 迷宫无解 。
最后此篇关于算法|迷宫求解的文章就讲到这里了,如果你想了解更多关于算法|迷宫求解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
滑动窗口限流 滑动窗口限流是一种常用的限流算法,通过维护一个固定大小的窗口,在单位时间内允许通过的请求次数不超过设定的阈值。具体来说,滑动窗口限流算法通常包括以下几个步骤: 初始化:设置窗口
表达式求值:一个只有+,-,*,/的表达式,没有括号 一种神奇的做法:使用数组存储数字和运算符,先把优先级别高的乘法和除法计算出来,再计算加法和减法 int GetVal(string s){
【算法】前缀和 题目 先来看一道题目:(前缀和模板题) 已知一个数组A[],现在想要求出其中一些数字的和。 输入格式: 先是整数N,M,表示一共有N个数字,有M组询问 接下来有N个数,表示A[1]..
1.前序遍历 根-左-右的顺序遍历,可以使用递归 void preOrder(Node *u){ if(u==NULL)return; printf("%d ",u->val);
先看题目 物品不能分隔,必须全部取走或者留下,因此称为01背包 (只有不取和取两种状态) 看第一个样例 我们需要把4个物品装入一个容量为10的背包 我们可以简化问题,从小到大入手分析 weightva
我最近在一次采访中遇到了这个问题: 给出以下矩阵: [[ R R R R R R], [ R B B B R R], [ B R R R B B], [ R B R R R R]] 找出是否有任
我正在尝试通过 C++ 算法从我的 outlook 帐户发送一封电子邮件,该帐户已经打开并记录,但真的不知道从哪里开始(对于 outlook-c++ 集成),谷歌也没有帮我这么多。任何提示将不胜感激。
我发现自己像这样编写了一个手工制作的 while 循环: std::list foo; // In my case, map, but list is simpler auto currentPoin
我有用于检测正方形的 opencv 代码。现在我想在检测正方形后,代码运行另一个命令。 代码如下: #include "cv.h" #include "cxcore.h" #include "high
我正在尝试模拟一个 matlab 函数“imfill”来填充二进制图像(1 和 0 的二维矩阵)。 我想在矩阵中指定一个起点,并像 imfill 的 4 连接版本那样进行洪水填充。 这是否已经存在于
我正在阅读 Robert Sedgewick 的《C++ 算法》。 Basic recurrences section it was mentioned as 这种循环出现在循环输入以消除一个项目的递
我正在思考如何在我的日历中生成代表任务的数据结构(仅供我个人使用)。我有来自 DBMS 的按日期排序的任务记录,如下所示: 买牛奶(18.1.2013) 任务日期 (2013-01-15) 任务标签(
输入一个未排序的整数数组A[1..n]只有 O(d) :(d int) 计算每个元素在单次迭代中出现在列表中的次数。 map 是balanced Binary Search Tree基于确保 O(nl
我遇到了一个问题,但我仍然不知道如何解决。我想出了如何用蛮力的方式来做到这一点,但是当有成千上万的元素时它就不起作用了。 Problem: Say you are given the followin
我有一个列表列表。 L1= [[...][...][.......].......]如果我在展平列表后获取所有元素并从中提取唯一值,那么我会得到一个列表 L2。我有另一个列表 L3,它是 L2 的某个
我们得到二维矩阵数组(假设长度为 i 和宽度为 j)和整数 k我们必须找到包含这个或更大总和的最小矩形的大小F.e k=7 4 1 1 1 1 1 4 4 Anwser是2,因为4+4=8 >= 7,
我实行 3 类倒制,每周换类。顺序为早类 (m)、晚类 (n) 和下午类 (a)。我固定的订单,即它永远不会改变,即使那个星期不工作也是如此。 我创建了一个函数来获取 ISO 周数。当我给它一个日期时
假设我们有一个输入,它是一个元素列表: {a, b, c, d, e, f} 还有不同的集合,可能包含这些元素的任意组合,也可能包含不在输入列表中的其他元素: A:{e,f} B:{d,f,a} C:
我有一个子集算法,可以找到给定集合的所有子集。原始集合的问题在于它是一个不断增长的集合,如果向其中添加元素,我需要再次重新计算它的子集。 有没有一种方法可以优化子集算法,该算法可以从最后一个计算点重新
我有一个包含 100 万个符号及其预期频率的表格。 我想通过为每个符号分配一个唯一(且前缀唯一)的可变长度位串来压缩这些符号的序列,然后将它们连接在一起以表示序列。 我想分配这些位串,以使编码序列的预
我是一名优秀的程序员,十分优秀!