简单迷宫问题的求解


假设这是一幅迷宫地图,‘0’表示通路,‘1’表示墙不能通过,‘entry’表示迷宫的入口。那么怎么从中找到出口呢?!这就是这篇文章要解决的问题。


一、思路:

我们可以利用回溯法的思想,也就是所谓的试探法:每走一步,我们都有上、下、左、右四个方向要去试探,如果该方向是‘0’,那么就继续向下走,并继续试探;否则退回一步,走另外一个方向...

此外,我们还要借助栈来存放走过的路径:向前走的时候每走一步将该位置push入栈,退回的时候pop退栈。

栈的模拟实现:点击打开链接

二、实现:

1.首先,我们需要从文件中读取数据(迷宫地图)

void InitMaze(int *a,int rows,int cols)		//读取文件
{
	FILE* pf =fopen("Maze.txt","r");
	assert(pf);
	for (int i=0; i<rows; i++)
	{
		for (int j=0; j<cols;)
		{
			char value = fgetc(pf);
			if (value == '0' || value == '1')
			{
				a[i*N+j] = value-'0';
				j++;
			}
		}
	}
}
2.接下来就是找通路的问题了:

在这一部分主要的有三部分:a.表示位置的结构体b.判断此位置是否能通过的函数

          c.最主要的一个函数------找通路

struct Pos
{
	int _row;
	int _col;
	Pos(int rows = 0, int cols = 0)
		:_row(rows)
		,_col(cols)
	{}
};

bool CheckAccess(int* maze,Pos pos)		//判断当前位置是否是通路
{
	if ((pos._row >= 0 ) && (pos._row < N)
		&& (pos._col >= 0) && (pos._col < N)
		&& (maze[pos._row*N+pos._col] == 0))
		return true;	//是通路
	return false;	//不是通路
}

void make_push(int* maze,Stack<Pos>& path,Pos pos)	//将当前位置压入栈
{
	path.Push(pos);		
	maze[pos._row*N+pos._col] = 2;		//将走过的路径标记为2
}

bool chech_exit(int* maze, int rows,int cols,Pos pos)	//判断是否走到出口
{
	if ((pos._row == rows-1) || (pos._col == cols-1) || (pos._row == 0))
	{
		return true;
	}
	return false;
}

bool GetPath(int* maze, int rows,int cols,Stack<Pos>& path,Pos entry)
{
	make_push(maze,path,entry);		//入口标记为2
	while(!path.Empty())
	{
		Pos cur = path.Top();	//每次读取栈顶的元素,即当前位置
		Pos next = cur;
		
		//上
		next._row -= 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);//将走过的路压入栈
			continue;
		}
		next._row += 1;
		//右
		next._col += 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);
			continue;
		}
		next._col -= 1;
		//下
		next._row += 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);
			continue;
		}
		next._row -= 1;
		//左
		next._col -= 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);
			continue;
		}
		next._col += 1;

		if (chech_exit(maze,rows,cols,next))	//判断出口
		{
			return true;
		}

		maze[cur._row*cols+cur._col]=3;   //退栈时将回路标记为3,只是为了体现回溯的思想
		path.Pop();  
	}
	return false;
}
3.打印迷宫

void Ptintmaze(int *a,int rows,int cols)		//打印迷宫
{
	for (int i=0; i<rows; i++)
	{
		for (int j=0; j<cols;j++)
		{
			cout<<a[i*N+j]<<' ';
		}
		cout<<endl;
	}
	cout<<endl;
}
三、总体代码实现

#pragma once

#include "Stack.h"<span style="white-space:pre">	</span>//这里是自己实现的栈

const int N=10;
void InitMaze(int *a,int rows,int cols)		//读取文件
{
	FILE* pf =fopen("Maze.txt","r");
	assert(pf);
	for (int i=0; i<rows; i++)
	{
		for (int j=0; j<cols;)
		{
			char value = fgetc(pf);
			if (value == '0' || value == '1')
			{
				a[i*N+j] = value-'0';
				j++;
			}
		}
	}
}
void Ptintmaze(int *a,int rows,int cols)		//打印迷宫
{
	for (int i=0; i<rows; i++)
	{
		for (int j=0; j<cols;j++)
		{
			cout<<a[i*N+j]<<' ';
		}
		cout<<endl;
	}
	cout<<endl;
}

struct Pos
{
	int _row;
	int _col;
	Pos(int rows = 0, int cols = 0)
		:_row(rows)
		,_col(cols)
	{}
};

bool CheckAccess(int* maze,Pos pos)		//判断当前位置是否是通路
{
	if ((pos._row >= 0 ) && (pos._row < N)
		&& (pos._col >= 0) && (pos._col < N)
		&& (maze[pos._row*N+pos._col] == 0))
		return true;	//是通路
	return false;	//不是通路
}

void make_push(int* maze,Stack<Pos>& path,Pos pos)	//将当前位置压入栈
{
	path.Push(pos);		
	maze[pos._row*N+pos._col] = 2;		//将走过的路径标记为2
}

bool chech_exit(int* maze, int rows,int cols,Pos pos)	//判断是否走到出口
{
	if ((pos._row == rows-1) || (pos._col == cols-1) || (pos._row == 0))
	{
		return true;
	}
	return false;
}

bool GetPath(int* maze, int rows,int cols,Stack<Pos>& path,Pos entry)
{
	make_push(maze,path,entry);		//入口标记为2
	while(!path.Empty())
	{
		Pos cur = path.Top();	//每次读取栈顶的元素,即当前位置
		Pos next = cur;
		
		//上
		next._row -= 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);//将走过的路压入栈
			continue;
		}
		next._row += 1;
		//右
		next._col += 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);
			continue;
		}
		next._col -= 1;
		//下
		next._row += 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);
			continue;
		}
		next._row -= 1;
		//左
		next._col -= 1;
		if (CheckAccess(maze,next))
		{
			make_push(maze,path,next);
			continue;
		}
		next._col += 1;

		if (chech_exit(maze,rows,cols,next))	//判断出口
		{
			return true;
		}

		maze[cur._row*cols+cur._col]=3;   //退栈时将回路标记为3
		path.Pop();  
	}
	return false;
}

void test_mase()
{
	int maze[N][N];
	InitMaze((int*)maze,N,N);
	Ptintmaze((int*)maze,N,N);

	Stack<Pos> path;
	cout<<"是否有通路?"<<GetPath((int*)maze,N,N,path,Pos(3,0))<<endl;
	Ptintmaze((int*)maze,N,N);
}

运行结果:





  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
程序在VC++ 6下顺利编译通过。 一、 实验目的: (1) 熟练掌握链栈的基本操作及应用。 (2) 利用链表作为栈的存储结构,设计实现一个求解迷宫的非递归程序。 二、实验内容: 【问题描述】 以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对信任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 【基本要求】 首先实现一个链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),……。 【测试数据】 迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出口。 1 2 3 4 5 6 7 8 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 以方阵形式输出迷宫及其通路。 输出: 请输入迷宫的长和宽:5 5 请输入迷宫内容: 0 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 迷宫的路径为 括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向) (1,1,1,↓) (2,1,2,→) (2,2,1,↓) (3,2,1,↓) (4,2,2,→) (4,3,1,↓) (5,3,2,→) (5,4,2,→) (5,5,0,) 迷宫路径探索成功!
Sure, 我可以为您提供一个 Python 迷宫求解器代码。该代码使用了深度优先搜索算法来解决迷宫问题。 ```python def maze_solver(maze, start, end): maze_rows = len(maze) maze_cols = len(maze[0]) solution_grid = [[0 for j in range(maze_cols)] for i in range(maze_rows)] # Check if start and end points are obstacles if maze[start[0]][start[1]] == 1 or maze[end[0]][end[1]] == 1: return "No Solution!" # Mark the starting cell in the solution grid solution_grid[start[0]][start[1]] = 1 # Define potential move directions - left, right, up, down move_directions = [[0, 1], [1, 0], [0, -1], [-1, 0]] # Recursive function to check for possible paths def solve_maze(curr_row, curr_col): # Check if the current position is the end cell if curr_row == end[0] and curr_col == end[1]: solution_grid[curr_row][curr_col] = 1 return True # Check all directions for a possible path for direction in move_directions: new_row = curr_row + direction[0] new_col = curr_col + direction[1] if (new_row >= 0 and new_row < maze_rows and new_col >= 0 and new_col < maze_cols and maze[new_row][new_col] == 0 and solution_grid[new_row][new_col] == 0): solution_grid[new_row][new_col] = 1 if solve_maze(new_row, new_col): return True # Backtracking solution_grid[new_row][new_col] = 0 return False if solve_maze(start[0], start[1]): return solution_grid else: return "No Solution!" ``` 请注意,这只是一个简单的例子实现,您可能需要进行一些修改,以使其适用于您的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值