每日一练·迷宫自走问题

        这是一道农专的itc上的1分题(感兴趣研究的小题目)但居然有截至时间?还是周日晚上10点前?这搞得人不得不去做做看了,于是乎,在周日晚上9点左右AC了这道小题,虽然谈不上难,但还是可以总结总结的。这道题题目如下:

        【问题描述】有一个 10 x 10 的迷宫,起点是‘S’,终点是‘E’,墙是‘#’,道路是空格。一个机器人从起点走到终点。当机器人走到一个通道块,前面已经没有路可走时,它会按照右下左上的顺序在四个方向选择从而继续走。如果机器人能够过,则留下足迹‘*’,如果走不通,则留下标记‘!’。

下面给出算法,请你模拟机器人的走法输出最终的状态。注意:务必使用栈实现。

图:迷宫算法

【输入形式】一个 10 x 10 的二维字符数组。

【输出形式】机器人走过的路径状态。

【样例输入】

##########

#S # # #

# # # #

# ## #

# ### #

# # #

# # # #

# ### ## #

## E#

##########

【样例输出】

##########

#**#!!!# #

# *#!!!# #

#**!!## #

#*### #

#***# #

# #***# #

# ###*## #

## #

##########

【样例说明】

位置,元素以及迷宫的类型定义:

typedef struct{

int r, c; // 以行号和列号作为“坐标位置”类型

}PosType;

typedef struct{

int ord; // 通道块在路径上的序号

PosType seat; // 通道块在迷宫中的“坐标位置”

int di; // 从此通道块走向下一通道块的“方向”

}SElemType; // 定义堆栈元素的类型

typedef struct{

char arr10;

}MazeType; // 定义迷宫类型(二维字符数组)

【升级版】你是否能够找出一条最近的路?并输出走法及总步数。如果有多条总步数相同的最近的路,能否将所有最近的路全部找出来?并输出总个数。

怎么说呢,这个图就是这么的糊,看与不看没什么区别,倒是以迷宫为主题可以看看迷宫饭了

        当然,回归这道题本身,用栈解决(参考我上篇文章的栈水题7必备内容:建栈,初始化栈,判断栈满,判断栈空,压栈,出栈,读栈),把这七个必备内容稍加修改,改成可以存储位置坐标与移动方向的栈即可。

        本题的难点在于两点,第一点就是这个题目给出来的这个迷宫是真的抽象啊,没对齐,不好说让人怎么去看,建议拿个记事本自己抄一个,不然别想成功读取过样例。本人自己是通过复制详细评判结果生成的内容去当样例的,类似于金针菇?

        然后就是最简单的c语言风格,一个个scanf进去,虽然土,但不会错就是啦

接着,本题的真正难点出现了,怎么去具体化走迷宫的方向?欸,聪明的我想到了简单的方法:1右 2下 3左 4上,这不就可以了吗,然后在具体化一下遇到'#''*''!'分别该怎么处理这一题就搞定了,虽然在实现的时候打错了三个地方导致我调试了一会

  1. 在判断结束时误写成了while(xx != ex&&yy !=ey);这样到了与E的同一行与同一列就结束了,应该改成while (xx!=ex||yy!=ey);
  2. 在写判断时i不会随着里面的if else变化,第一次最后一个判断偷了懒直接写else导致陷入了前进后退前进后退的死循环,改为else if(i==5)解决
  3. 在写第四个判断语句时有打错的地方,再次陷入死循环,经调试修改后解决

总结而言,虽然是一道水题,但太久没写和差劲的代码水平只能让我不断地改,请未来的我记下这些bug,争取以后不再出错

本题题解(基础版,非最优版):之后有时间可以考虑一下后面的高阶版

#include<iostream>
#include<cstdio>
using namespace std;
#define Stack_Size 100
//终于在10点前完成了,迷宫酱你太令我感到欢喜了
char mape1[12][12];
int dizhi[12][12];
int sx, sy, ex, ey;

typedef struct
{
	//方向简化一下,1右 2下 3左 4上
	int Fangxiang[Stack_Size];
	int Yzhou[Stack_Size];
	int Xzhou[Stack_Size];
	int top;
}nStack;

void nInitStack(nStack* S)
{
	S->top = -1;
}

int nIsFull(nStack* S)
{
	return(S->top == Stack_Size - 1 ? 1 : 0);
}

int nPop(nStack* S, int* x, int* y, int* fang)
{
	if (S->top == -1)
		return 0;
	else
	{
		*x = S->Xzhou[S->top];
		*y = S->Yzhou[S->top];
		*fang = S->Fangxiang[S->top];
		S->top--;
		return 1;
	}
}

int nGetTop(nStack* S, int* x, int* y, int* fang)
{
	if (S->top == -1)
		return 0;
	else
	{
		*x = S->Xzhou[S->top];
		*y = S->Yzhou[S->top];
		*fang = S->Fangxiang[S->top];
		return 1;
	}
}

int nPush(nStack* S, int x, int y, int fang)
{
	if (S->top == Stack_Size - 1) return 0;
	S->top++;
	S->Xzhou[S->top] = x;
	S->Yzhou[S->top] = y;
	S->Fangxiang[S->top] = fang;
	return 1;
}



void func()
{
	nStack Jilu;
	nInitStack(&Jilu);
	//读取迷宫
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			scanf("%c", &mape1[i][j]);
		}
		getchar();
	}

	//得起点和终点
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			if (mape1[i][j] == 'S')
			{
				sx = j;
				sy = i;
			}
			if (mape1[i][j] == 'E')
			{
				ex = j;
				ey = i;
			}
		}

	}

	//从起点出发找终点,1右 2下 3左 4上
	int xx = sx;
	int yy = sy;
	int tt = 0;

	while (xx != ex || yy != ey)
	{
		for (int i = 1; i <= 5; i++)
		{
			if (i == 1 && mape1[yy][xx + 1] != '#' && mape1[yy][xx + 1] != '*' && mape1[yy][xx + 1] != '!')
			{
				mape1[yy][xx] = '*';
				nPush(&Jilu, xx, yy, i);
				xx++;
				break;
			}

			else if (i == 2 && mape1[yy + 1][xx] != '#' && mape1[yy + 1][xx] != '*' && mape1[yy + 1][xx] != '!')
			{
				mape1[yy][xx] = '*';
				nPush(&Jilu, xx, yy, i);
				yy++;
				break;
			}

			else if (i == 3 && mape1[yy][xx - 1] != '#' && mape1[yy][xx - 1] != '*' && mape1[yy][xx - 1] != '!')
			{
				mape1[yy][xx] = '*';
				nPush(&Jilu, xx, yy, i);
				xx--;
				break;
			}

			else if (i == 4 && mape1[yy - 1][xx] != '#' && mape1[yy - 1][xx] != '*' && mape1[yy - 1][xx] != '!')
			{
				mape1[yy][xx] = '*';
				nPush(&Jilu, xx, yy, i);
				yy--;
				break;
			}

			else if (i == 5)
			{
				mape1[yy][xx] = '!';
				nPop(&Jilu, &xx, &yy, &tt);
			}


		}
	}
	mape1[ey][ex] = '*';
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			cout << mape1[i][j];
		}
		cout << endl;
	}

}

int main()
{
	func();
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值