用栈解决迷宫问题求出路径

1.用栈解决迷宫问题,比较暴力,实际上是经过大量的试错才得出的路径
问题分析

a.首先画出图,我用1代表墙,用0代表非墙。
b.首先要规定入口的坐标位置
c.然后规定寻找的方向规则比如 先每到一个位置先看下该点的左侧是否非墙,如果是返回该点的坐标并将该点对应的下标(在之后要用该下标解析出对应的坐标)入栈,如果是墙的话,就看该点的下面是否非墙…总之我规定的顺序是左-下-右-上。(这个也是该代码的灵魂所在)。
d.上面当你遇到死胡同时该怎么办,那么就要考虑出栈了(这时就要将下标套现成坐标)然后再进行上述的方向判断,但是你想想是不是还欠点什么,当你第一次判断该点的下方可行的时候将该点进栈,当你出去的时候在进行判断,是不是还要进入该点的下方,那么此时就会陷入死循环,别急,那么我们就需要设置一个判断是否来过该点的标志visited[2]={0,1},0代表没来过,1代表来过,所以在最开始的时候要遍历图将图全部初始化为未来过。

话不多说代码奉上

#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef struct
{
	int stack[MAXSIZE];//顺序栈
	int top;
}STACK,*SeqStack;
void initStack(SeqStack S)//初始化要将地址传进去
{
	memset(S->stack, 0, sizeof(S->stack));//初始化函数
	S->top = -1;
}
void Push(SeqStack S, int way)//入栈
{

	if (S->top == MAXSIZE - 1)
	{
		printf("栈已满\n");
	}
	else
	{
		(S->top)++;
		S->stack[S->top] = way;//栈存的元素是按照1-100的顺序存的
	}
}
void Pop(SeqStack S)//出栈让其返回坐标
{
	if (S->top == -1)
	{
		printf("栈已空\n");
	}
	else
	{
	   S->stack[--S->top];
	}
}
int* IsPass(SeqStack S, char map[][10],int visited[][10],int *arr)
{
	if (map[arr[0]][arr[1]-1] != 1)//左
	{
		if (visited[arr[0]][arr[1]-1] != 1)
		{
			Push(S, 10 * arr[0] + arr[1]-1);//入栈之后将该位置赋值为1代表访问过该点
			visited[arr[0]][arr[1]-1] = 1;//判断该点来过
		    arr[1] = arr[1] - 1;	//更新坐标
			map[arr[0]][arr[1]] = 1;//将该点的内容变为墙。//该处有些小问题,你可以在最后打印图的时候用是否访问过来打印图。我只是为了找到路径,所以改变非墙的信息是可以的。
		}//将标号入栈
	}
	else if (map[arr[0] + 1][arr[1]] != 1)//下
	{
		if (visited[arr[0] + 1][arr[1]] != 1)
		{
			Push(S, 10 * (arr[0] + 1) + arr[1]);
			visited[arr[0] + 1][arr[1]] = 1;
			arr[0] = arr[0] + 1;
			map[arr[0]][arr[1]] = 1;
		}
	}
	else if (map[arr[0]][arr[1] + 1] != 1)//右
	{
		if (visited[arr[0]][arr[1] + 1] != 1)
		{
			Push(S, 10 * arr[0] + arr[1] + 1);
			visited[arr[0]][arr[1] + 1] = 1;
			arr[1] = arr[1] + 1;
			map[arr[0]][arr[1]] = 1;
		}
	}
	else if (map[arr[0] - 1][arr[1]] != 1)//上
	{
		if (visited[arr[0] - 1][arr[1]] != 1)
		{
			Push(S, 10 * (arr[0] - 1) + arr[1]);
			visited[arr[0] - 1][arr[1]] = 1;
			arr[0] = arr[0] - 1;
			map[arr[0]][arr[1]] = 1;
		}
	}
	else//遇到死胡同该怎么办将ij点的信息出栈
	{
		Pop(S);//出栈后但是i,j没发生变化
		int a = S->stack[S->top];
		arr[0] = a / 10;
		arr[1] = a % 10;
	}
	return arr;
}//方向判断
void print(SeqStack S)
{
	int a, b;
	for (int i = 0; i < S->top; i++)
	{
		a = S->stack[i] / 10;
		b = S->stack[i] % 10;
		printf("(%d,%d)\t", a, b);
	}
}
void Graph(char map[][10])
{
	for (int i = 0; i < 10; ++i)
	{
		for (int j = 0; j < 10; ++j)
		{
			if (map[i][j] == 1)
			{
				printf("■");
			}
			else
			{
				if ((i == 1 && j == 1) || (j == 8 && i == 8))
				{
					printf("OO");//因为上述的`■`占两个字节
				}
				else
				{
					printf("  ");//两个空格
				}

			}
		}
		printf("\n");
	}
}
int main()
{
	char map[10][10] = {//1表示墙,0表示可走的路//地图
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 },
		{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 },
		{ 1, 0, 0, 0, 0, 1, 1, 0, 0, 1 },
		{ 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 },
		{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
		{ 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 },
		{ 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 },
		{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } 
	};
	Graph(map);
	int visited[10][10] = { 0 };
	SeqStack S;
	S = (SeqStack)malloc(sizeof(STACK));//定义对象
	initStack(S);//初始化
	int i = 1, j = 1;
	visited[i][j] = 1;
	int arr[2] = { i,j };
	do
	{
		IsPass(S, map,visited, arr);//
	} while (!(arr[0]==8&&arr[1]==8));
	/*printf("找到的路径图如下:\n");
	for (i = 0; i < S->top; i++)
	{
		printf("%d\t", S->stack[i]);
	}*/
	printf("找到的路径图如下:\n");
	print(S);
    system("pause");
	return 0;
}

在这里插入图片描述

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
问题描述: 以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫求出入口(0,0)到出口(m-1,n-1)的通路和通路总数,或得出没有通路的结论。例如下图, 0(入口) 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0(出口) 从入口出口有6条不同的通路。 而下图: 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 从入口出口则没有通路。 算法设计: 给定一个m*n的长方阵表示迷宫,设计算法输出入口出口的通路和通路总数,或得出没有通路的结论。 算法提示: 和皇后问题与分书问题类似。可以用二维数组存储迷宫数据,对于迷宫中任一位置,均可约定有东、南、西、北四个方向可通。从当前位置a(用(x,y)表示一个位置,假定它是以向右的x轴和向下的y轴组成的平面上的一个点)出发依次尝试四个方向是否有路,若某个方向的位置b可通,则按照同样的方法继续从b出发寻找。若到达出口,则找到一条通路。 数据输入: 由文件input.txt 提供输入数据。第一行是m和n的值,空格分隔,其后共m行。每行有n个数字,数和数之间用空格分隔。 结果输出: 将计算出的所有从入口出口的通路输出到文件output.txt 中。若没有通路,则将0写入文件中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值