走迷宫问题(待续)

前置代码:

struct pos
{
	pos(int row = 0, int col = 0)
		:_row(row)
		,_col(col)
	{}
	int _row;
	int _col;
};

void GetMaze(int *arr,  int n)
{
	FILE *fout = fopen("MazeMap.txt", "r");
	assert(fout);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n;)
		{
			char ch = fgetc(fout);
			if (ch != ‘ ‘ && ch != ‘\n‘)
			{
				*(arr + i * n + j) = ch - ‘0‘;
				j++;
			}
		}
	}
}

一、找到出口

bool MazePath(int *arr, int n, const pos &entry, stack<pos> &path)   //假设下边沿为迷宫的出口
{
	pos cur = entry;
	path.push(cur);
	while (!path.empty())
	{
		*(arr + n * (cur._row)+cur._col) = 2;
		if (cur._row == n - 1)
		{
			return true;
		}
		//向下
		if 
		((cur._row + 1 < 10) && (*(arr + n * (cur._row + 1) + cur._col) == 0)) 
		{
			*(arr + n * (cur._row + 1) + cur._col) = 2;
			++cur._row;
			path.push(cur);
			continue;
		}
		//向上
		if 
		((cur._row - 1 >= 0) && (*(arr + n * (cur._row - 1) + cur._col) == 0))  
		{
			*(arr + n * (cur._row - 1) + cur._col) = 2;
			--cur._row;
			path.push(cur);
			continue;
		}
		//向左
		if 
		((cur._col - 1 >= 0) && (*(arr + n * cur._row + cur._col - 1) == 0))     
		{
			*(arr + n * cur._row + cur._col - 1) = 2;
			--cur._col;
			path.push(cur);
			continue;
		}
		//向右
		if ((cur._col + 1 < 10) && (*(arr + n * cur._row + cur._col + 1) == 0))      
		{
			*(arr + n * cur._row + cur._col + 1) = 2;
			++cur._col;
			path.push(cur);
			continue;
		}

		//走不通
		cur._col = path.top()._col;
		cur._row = path.top()._row;
		path.pop();
	}
}

二、找到所有出口并得出最短路线(最优解)

template <typename T>
void ClearPath(stack<T> &stack)
{
	while (!stack.empty())
	{
		stack.pop();
	}
}

static void SaveBestPath(stack<pos> &path, vector< stack<pos> > path_vec)
{
	stack<pos> best_path;
	int sz = (path_vec.back()).size();
	best_path = path_vec.back();
	while (!path_vec.empty())
	{
		if (sz > (path_vec.front()).size())
		{
			best_path = path_vec.front(); 
		}
		path_vec.pop_back();
	}
	path = best_path;
}

static struct Exit
{
	Exit(int row, int col)
		:_row(row)
		,_col(col)
	{}
	int _row;
	int _col;
};

 //堵住已知的出口    (为了不销毁数据,不使用引用)
static void BlockKnownExit(int *arr, vector< Exit> exit_vec, int n)
{
	Exit ext1 = exit_vec.back();
	while (!exit_vec.empty())
	{
		ext1 = exit_vec.back();
		*(arr + n * ext1._row + ext1._col) = 3;
		exit_vec.pop_back();
	}
}

//假设下边沿为迷宫的出口
bool MazePathMin(int *arr, int n, const pos &entry, stack<pos> &path)  
{
	vector< stack<pos> > path_vec;   //用于存放所有的路径
	vector< Exit > exit_vec;         //用于存储所有出口
	pos cur = entry;
	path.push(cur);

	while (!path.empty() )
	{
		*(arr + n * (cur._row) + cur._col) = 2;
		if (cur._row == n - 1)
		{
			//找到一个出口
			*(arr + n * (cur._row) + cur._col) = 3;
			Exit ext_tmp(cur._row, cur._col);
			path_vec.push_back(path);
			exit_vec.push_back(ext_tmp);

			//清空路径,寻找除该出口外的其他出口
			ClearPath(path);
			GetMaze(arr, n);
			BlockKnownExit(arr, exit_vec, n);
			cur = entry;
			path.push(cur);
		}
                 //向下
		if ((cur._row + 1 < 10) && (*(arr + n * (cur._row + 1) + cur._col) == 0))
		{
			*(arr + n * (cur._row + 1) + cur._col) = 2;
			++cur._row;
			path.push(cur);
			continue;
		}
		//向上
		if ((cur._row - 1 >= 0) && (*(arr + n * (cur._row - 1) + cur._col) == 0))  
		{
			*(arr + n * (cur._row - 1) + cur._col) = 2;
			--cur._row;
			path.push(cur);
			continue;
		}
		//向左
		if ((cur._col - 1 >= 0) && (*(arr + n * cur._row + cur._col - 1) == 0))     
		{
			*(arr + n * cur._row + cur._col - 1) = 2;
			--cur._col;
			path.push(cur);
			continue;
		}
		//向右
		if ((cur._col + 1 < 10) && (*(arr + n * cur._row + cur._col + 1) == 0))      
		{
			*(arr + n * cur._row + cur._col + 1) = 2;
			++cur._col;
			path.push(cur);
			continue;
		}

		//走不通的时候:
		cur._col = path.top()._col;
		cur._row = path.top()._row;
		path.pop();
	}

	//path为空
	SaveBestPath(path, path_vec);   //把最佳的路径保存进path中(仍然倒序)
	return (!path.empty());
}

三、用递归实现

时间: 2024-10-22 11:06:48

走迷宫问题(待续)的相关文章

NYOJ306 走迷宫(dfs+二分搜索)

题目描述 http://acm.nyist.net/JudgeOnline/problem.php?pid=306 Dr.Kong设计的机器人卡多非常爱玩,它常常偷偷跑出实验室,在某个游乐场玩之不疲.这天卡多又跑出来了,在SJTL游乐场玩个不停,坐完碰碰车,又玩滑滑梯,这时卡多又走入一个迷宫.整个迷宫是用一个N * N的方阵给出,方阵中单元格中填充了一个整数,表示走到这个位置的难度. 这个迷宫可以向上走,向下走,向右走,向左走,但是不能穿越对角线.走迷宫的取胜规则很有意思,看谁能更快地找到一条路

青蛙走迷宫问题(体力值)

题目: 青蛙走迷宫,1代表路通,0代表不通:起点是(0, 0),终点是(0,m - 1);青蛙每次向上走需要消耗体力值为3,向下走不消耗体力值,平走消耗体力值1:根据给定值判断青蛙是否可以根据初始值到达终点,并求出消耗体力值最少的路径: 举例: n = 4, m =4, p = 10(体力值) 4 4 10 1 0 0 1 1 1 0 1 0 1 1 1 0 0 1 1 则结果为:[[0, 0], [1, 0], [1, 1], [2, 1], [2, 2], [2, 3], [1, 3], [

深度优先算法——走迷宫的实现

深度优先搜索算法(Depth-First-Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止.如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止.属于盲目搜索. 深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图

走迷宫

走迷宫 时限:1000ms 内存限制:10000K  总时限:3000ms 描述 判断是否能从迷宫的入口到达出口 输入 先输入两个整数表示迷宫的行数m和列数n,再输入口和出口的坐标,最后分m行输入迷宫,其中1表示墙,0表示空格每个数字之间都有空格. 输出 若能到达,则输出"Yes",否则输出"No",结果占一行. 输入样例 3 30 02 20 0 01 1 00 1 0 输出样例 Yes #include <iostream> using namesp

【老鼠走迷宫二】

/* 老鼠走迷宫二 有问题 */ #include <stdio.h> #include <stdlib.h> void visit(int ,int); int maze[9][9] = { {2, 2, 2, 2, 2, 2, 2, 2, 2}, {2, 0, 0, 0, 0, 0, 0, 0, 2}, {2, 0, 2, 2, 0, 2, 2, 0, 2}, {2, 0, 2, 0, 0, 2, 0, 0, 2}, {2, 0, 2, 0, 2, 0, 2, 0, 2}, {

算法:老鼠走迷宫问题

算法:老鼠走迷宫问题(初) [写在前面] 老鼠走迷宫问题的递归实现,是对递归思想的一种应用. [问题描述] 给定一个二维数组,数组中2表示墙壁,0表示通路,由此数组可展示为一个迷宫图.给定入口位置和出口位置,判断之间是否存在通路并显示出走出迷宫的道路. [代码] 对题目的描述部分 int migo[7][7]={ {2, 2, 2, 2, 2, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 0, 2, 0, 2, 0, 2}, {2, 0, 0, 0, 0, 2, 2},

数据结构之深度优先搜索(走迷宫)

在此以走迷宫为例: 给定迷宫起点和终点,看能否到达:(xt,yt) void f(int x,int y){ if(x<0||x>21||y<0||y>21){//判断是否超出迷宫 return; } ch[x][y]='#'; for(i=0;i<4;i++){if(ch[x][y]=='.'){ if(x==xt+1&&y==yt+1){ flag=1; return ; } //四个方向 f(x,y+1); f(x,y-1); f(x+1,y); f(x

走迷宫——C++ 算法实现

这两个看了几个不错的走迷宫算法,然后按照自己的方式写了一个实现,代码如下: MyMazeMap.cpp 1 #include <iostream> 2 #include <Windows.h> 3 #include "MazeMap.h" 4 #include "Mazer.h" 5 using namespace std; 6 7 const int SUCCESS = 0; 8 9 int main() 10 { 11 int map[8

第四章 搜索(深度、广度搜索、全排列、走迷宫、再解炸弹人、宝岛探险、水管工游戏)

一.深度优先搜索DFS 深度优先搜索DFS的关键思想是:当下应该怎么做(每个方法都试一遍),这一步解决后,进入下一步,下一步的解决方法和这一步的解决方法是一样的 DFS的基本模型 void dfs(int step) { 判断边界 尝试每一种可能  for(i=1;i<=n;i++) { 继续下一步 dfs(step+1) } 返回 } 1.1全排列 1 //输入一个数n 2 //输出1-n的全排列 3 #include <stdio.h> 4 int n, book[10], a[10

【每天一道算法题】走迷宫

输入描述: 输入包含多组数据. 每组数据包含一个10*10,由“#”和“.”组成的迷宫.其中“#”代表墙:“.”代表通路. 入口在第一行第二列:出口在最后一行第九列. 从任意一个“.”点都能一步走到上下左右四个方向的“.”点. 输出描述: 对应每组数据,输出从入口到出口最短需要几步. 输入例子: #.#########........##........##........##........##........##........##........##........#########.#