迷宫问题 by:192132-01 mfcheer

迷宫问题

以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

要求:

(1)首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。

(2)测试几组数据,数据的规模由小变大,即网格越来越小,障碍越来越复杂。

(3)实现该问题的可视化界面。

#include<stdio.h>
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<algorithm>
#include<vector>
#include<string.h>
#include<stack>
#include<set>
#include<map>
#include<sstream>
#include<time.h>
#include<utility>
#include<malloc.h>
#include<stdexcept>
#include<iomanip>
#include<iterator>  

using namespace std;

int n, m, sx, sy, ex, ey, t;
int p[110][110];

int vis[110][110];
int dir[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };

struct node
{
	int x;
	int y;
};

struct node pre[30][30];//存储节点前一个位置

//////////////////////////  栈
#define DataType node               

struct Node;
typedef struct Node *PNode;         

typedef struct Node
{
	DataType info;
	PNode link;
}Node;

typedef struct LinkStack
{
	PNode top;
}LinkStack;

typedef struct LinkStack * PLinkStack;
PLinkStack createEmptyStack(void);
int isEmptyStack(PLinkStack stack);
int push(PLinkStack stack, DataType x);
int pop(PLinkStack stack);
DataType getTop(PLinkStack stack);
void showStack(PLinkStack stack);
void setEmpty(PLinkStack stack);
void destroyStack(PLinkStack stack);

PLinkStack createEmptyStack(void)
{
	PLinkStack stack = (PLinkStack)malloc(sizeof(struct LinkStack));
	if (stack == NULL)
		printf("存储分配失败,请重建栈!\n");
	else
		stack->top = NULL;
	return stack;
}

int isEmptyStack(PLinkStack stack)
{
	return (stack->top == NULL);
}

int push(PLinkStack stack, DataType x)
{
	PNode p = (PNode)malloc(sizeof(struct Node));
	if (p == NULL)
	{
		printf("新结点分配内存失败,进栈失败,请重试!\n");
		return 0;
	}
	else
	{
		p->info = x;
		p->link = stack->top;
		stack->top = p;
		return 1;
	}
}

int pop(PLinkStack stack)
{
	if (isEmptyStack(stack))
	{
		printf("栈为空!\n");
		return 0;
	}
	else
	{
		PNode p;
		p = stack->top;   //删除最后一个结点
		stack->top = stack->top->link;
		free(p);
		return 1;
	}
}

DataType getTop(PLinkStack stack)
{
	if (isEmptyStack(stack))
	{
		printf("栈为空!取栈顶元素失败!\n");
	}
	return (stack->top->info);
}

void showStack(PLinkStack stack)
{
	if (isEmptyStack(stack))
		printf("当前栈为空!无内容可显示。\n");
	else
	{
		PNode p;
		p = stack->top;
		printf("顶--> ");
		while (p->link != NULL)
		{
			printf("%d ", p->info);
			p = p->link;
		}
		printf("%d ", p->info);
		printf("-->底\n");
	}
}

void setEmpty(PLinkStack stack)
{
	stack->top = NULL;
}

void destroyStack(PLinkStack stack)
{
	if (stack)
	{
		stack->top = NULL;
		free(stack);
	}
}
///////////////////////////

int check(int x, int y)
{
	if (x >= 0 && x < m && y >= 0 && y < n)
		return 1;
	return 0;
}

void printf_path()
{
	node ss,sss;

	DataType data;
	PLinkStack stack;

	stack = createEmptyStack();

	ss.x = 4;
	ss.y = 4;

	while (1)
	{
		push(stack, ss);
		if (ss.x == sx && ss.y == sy)
			break;
		ss = pre[ss.x][ss.y];
	}

	int pres, presy;

	while (!(isEmptyStack(stack)))
	{
		ss = getTop(stack);
		pop(stack);
		if (!(isEmptyStack(stack)))
			sss = getTop(stack);
		printf("此刻坐标(%d, %d)  ", ss.x, ss.y);

		if (!(isEmptyStack(stack)))
		{
			if (sss.x == ss.x && sss.y == ss.y + 1)
				printf("向右走\n");
			if (sss.x == ss.x && sss.y == sss.y - 1)
				printf("向左走\n");
			if (sss.x == ss.x + 1 && sss.y == sss.y)
				printf("向下走\n");
			if (sss.x == ss.x - 1 && sss.y == sss.y)
				printf("向上走\n");
		}
	}printf("到达终点!\n");
}

////////////////////////队列

#define Error( str )        FatalError( str )
#define FatalError( str )   fprintf( stderr, "%s\n", str ), exit( 1 )
#define  ElementType node

#define MAXQUEUE 100

typedef struct NODE
{
	ElementType data;
	struct NODE* nextNode;
} NODE;
typedef struct queue
{
	NODE* front;    // 对首指针
	NODE* rear;     // 队尾指针
	int items;      // 队列中项目个数

} *ptrQueue;
typedef ptrQueue Queue;
int IsEmpty(Queue q);
int IsFull(Queue q);
Queue CreateQueue(void);
void DisposeQueue(Queue q);
void MakeEmpty(Queue q);
void Enqueue(ElementType x, Queue q);
ElementType Front(Queue q);
void Dequeue(Queue q);

int IsFull(Queue q)
{
	return q->items == MAXQUEUE;
}

int IsEmpty(Queue q)
{
	return q->items == 0;
}
Queue CreateQueue(void)
{
	Queue q;

	q = (Queue)malloc(sizeof(struct NODE));
	if (NULL == q)
		Error("空间不足,队列内存分配失败!");

	q->front = (NODE*)malloc(sizeof(NODE));
	if (NULL == q->front)
		Error("空间不足,队列首节点内存分配失败!");

	q->rear = (NODE*)malloc(sizeof(NODE));
	if (NULL == q->rear)
		Error("空间不足,队列尾节点内存分配失败!");

	q->items = 0;

	return q;
}

void DisposeQueue(Queue q)
{
	MakeEmpty(q);
	free(q);
}

void MakeEmpty(Queue q)
{
	if (q == NULL)
		Error("必须先使用CreateQueue创建队列!");

	while (IsEmpty(q))
		Dequeue(q);
}

void Enqueue(ElementType x, Queue q)
{
	if (IsFull(q))
		Error("队列已满!");

	NODE* pnode;
	pnode = (NODE*)malloc(sizeof(NODE));
	if (NULL == pnode)
		Error("新节点分配内存失败!");

	pnode->data = x;
	pnode->nextNode = NULL;
	if (IsEmpty(q))
		q->front = pnode;           // 项目位于首端
	else
		q->rear->nextNode = pnode;  // 链接到队列尾端
	q->rear = pnode;                    // 记录队列尾端的位置
	q->items++;                     // 项目数加1

	return;
}

void Dequeue(Queue q)
{
	if (IsEmpty(q))
		Error("队列本身为空!");

	NODE* pnode;
	pnode = q->front;
	q->front = q->front->nextNode;
	free(pnode);

	q->items--;
	if (q->items == 0)
		q->rear = NULL;

	return;
}

ElementType Front(Queue q)
{
	if (!IsEmpty(q))
		return q->front->data;
	Error("队列为空\n");
}

ElementType FrontAndDequeue(Queue q)
{
	ElementType x;

	if (IsEmpty(q))
		Error("队列为空!");
	else
	{
		q->items--;
		x = q->front->data;
		q->front = q->front->nextNode;
	}

	return x;
}

///////////////////////

int bfs()
{
	memset(vis, 0, sizeof(vis));

	Queue sqQueue;
	sqQueue = CreateQueue();

	node qq, qqq;

	qq.x = sx;
	qq.y = sy;
	vis[sx][sy] = 1;

	Enqueue(qq, sqQueue);

	while (!IsEmpty(sqQueue))
	{
		qq = Front(sqQueue);
		Dequeue(sqQueue);

		if (qq.x == ex && qq.y == ey)
		{
			printf_path();
			return 1;
		}

		for (int i = 0; i < 4; i++)
		{
			int x = qq.x + dir[i][0];
			int y = qq.y + dir[i][1];

			if (!check(x, y) || vis[x][y] || p[x][y] == 1)
				continue;

			qqq = qq;
			qqq.x = x;
			qqq.y = y;

			pre[qqq.x][qqq.y] = qq;

			vis[x][y] = 1;
			Enqueue(qqq, sqQueue);
		}
	}
	return 0;
}

int main()
{
	printf("请输入地图长和宽\n");
	while (cin >> m >> n)
	{
		printf("输入起点坐标和重点坐标\n");
		scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
		printf("请输入地图\n");
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < n; j++)
			{
				cin >> p[i][j];
			}
		}
		int ans = bfs();
		if (ans == 0)
			printf("不存在起点到终点的通路\n\n\n\n");
			printf("\n\n\n\n");
		printf("是否继续 1.yes 2.no\n ");
			scanf("%d",&t);
			if (t == 2) { printf("          再见   ,谢谢使用本系统!\n\n\n"); return 0; }
		printf("\n\n\n\n");
		printf("请输入地图长和宽\n");
	}
	return 0;
}

测试数据:

5 5

0 0 4 4

0 1 0 0 0

0 1 0 1 0

0 0 0 0 0

0 1 1 1 1

0 0 0 1 0

1

5 5

0 0 4 4

0 1 0 0 0

0 1 0 1 0

0 0 0 0 0

0 1 1 1 0

0 0 0 1 0

2

时间: 2024-11-04 00:12:26

迷宫问题 by:192132-01 mfcheer的相关文章

我喜欢减肥我们来减肥吧

http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313278016/2015.01.28.html http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313282016/2015.01.28.html http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313289016/2015.01.28.html http://www.ebay.com/cln/usli

百度回家看沙发沙发是减肥了卡斯加积分卡拉是减肥

http://www.ebay.com/cln/hpryu-caw8ke/cars/158056866019/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/158445650015/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/158445674015/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/1584456790

巢哑偕倥乇椭煞谙暗逞帕俸

IEEE Spectrum 杂志发布了一年一度的编程语言排行榜,这也是他们发布的第四届编程语言 Top 榜. 据介绍,IEEE Spectrum 的排序是来自 10 个重要线上数据源的综合,例如 Stack Overflow.Twitter.Reddit.IEEE Xplore.GitHub.CareerBuilder 等,对 48 种语言进行排行. 与其他排行榜不同的是,IEEE Spectrum 可以让读者自己选择参数组合时的权重,得到不同的排序结果.考虑到典型的 Spectrum 读者需求

我国第三代移动通信研究开发进展-尤肖虎200106

众所周知,数据科学是这几年才火起来的概念,而应运而生的数据科学家(data scientist)明显缺乏清晰的录取标准和工作内容.此次课程以<星际争霸II>回放文件分析为例,集中在IBM Cloud相关数据分析服务的应用.面对星际游戏爱好者希望提升技能的要求,我们使用IBM Data Science Experience中的jJupyter Notebooks来实现数据的可视化以及对数据进行深度分析,并最终存储到IBM Cloudant中.这是个介绍+动手实践的教程,参会者不仅将和讲师一起在线

pl/sql学习1——标量变量psahnh6S

为类型.不能用于表列的数据类型.范围为的子类型.自然数.为的子类型.具有约束为单精度浮点数.为变量赋值时.后面要加为双精度浮点数.为变量赋值时.后面要加.为数字总位数.为小数位数是的子类型.最大精度位是的子类型.最大精度位单精度浮点型是的子类型.最大精度位双精度浮点型定义精度为位的实数..定义为位的整数.变长字符串.最长测试变量数据!.定长字符串.最长测试变长二进制字符串物理存储的为类型...固定长度.个字节使用定义数据类型那个最小值:最大值:最小值:最大值:最小值:最大值:最小值:最大值:最小

洛谷——P1141 01迷宫

https://www.luogu.org/problem/show?pid=1141 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身). 输入输出格式 输入格式: 输入的第1行为两个正整数n,m. 下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格. 接下来m行,每行2个用空格分隔的正整

P1141 01迷宫

题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身). 输入输出格式 输入格式: 输入的第1行为两个正整数n,m. 下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格. 接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格. 输出格式

luogu cogs P1141 01迷宫

题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身). 输入输出格式 输入格式: 输入的第1行为两个正整数n,m. 下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格. 接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格. 输出格式

luogu P1141 01迷宫 x

P1141 01迷宫 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身). 输入输出格式 输入格式: 输入的第1行为两个正整数n,m. 下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格. 接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移

洛谷OJ P1141 01迷宫 解题报告

洛谷OJ P1141 01迷宫 解题报告 by MedalPluS [题目描述]    有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上.你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身).   [输入描述]   输入的第1行为两个正整数n,m.  下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格.  接下来m行,每行2个用空格分隔的正整数i,j,对