亲测可行:
使用蓝桥杯比赛编译器:DEV C++
求迷宫中从入口到出口的路径是一个经典的程序设计问题,通常采用“穷举求解”的方法,即顺着某一方向向前探索,若能走通,则继续往前走;否则原路返回,换一个方向继续探索,直至所有可能的通路都探索到为止。 因此,在求解迷宫问题的时候应用“栈”也就是自然而然的事了。 对于程序来说:
1.我们需要规定一个方向作为主方向,使得“自己”的位置不断移动,直到“遇到走不通的地方”或者是“遇到之前走过的地方”。
方向定义:
东:1
南:2
西:3
北:4
2.我们需要直到我们经过哪些地方,在这里我们将除栈顶外的其他元素视为“经过的地方”!!!
3.我们需要一个二维数组存放“迷宫”,还需要一个二维数组存放“走过的地方”。
迷宫:
走过的地方:(这里把所有地点初始化为0,代表尚未经过,经过的地方会被重新赋值为1)
4.最后,当我们“走”到终点的时候,路径的每一个“点”都会存放到“栈”中,我们将其依次弹出即可得到最终路径。
过程截图:
栈: 顺序栈,栈中每一个结构体对应一个点,x表示该点的横坐标,y表示该点的纵坐标,direction表示该点的方向。 代码实现:
#include#include #define MAXSIZE 10 //定义迷宫 int arr[MAXSIZE][MAXSIZE] = { 1,1,1,1,1,1,1,1,1,1, 1,0,0,1,1,1,1,1,1,1, 1,1,0,1,0,0,0,0,1,1, 1,1,0,1,0,1,1,0,1,1, 1,1,0,0,0,1,1,0,1,1, 1,1,0,1,0,1,1,0,1,1, 1,1,0,1,0,1,1,0,1,1, 1,1,0,1,0,1,1,0,1,1, 1,1,0,0,0,0,1,0,2,1, 1,1,1,1,1,1,1,1,1,1 }; //行走过的标志 int arr_tar[MAXSIZE][MAXSIZE] = {0}; //栈的数据域 typedef struct Stack { int x; int y; int direction; }Stack; //顺序栈 typedef struct SqStack { Stack* base; int top; }SqStack; //初始化 void InitStack(SqStack* stack) { stack->base = (Stack*)malloc(MAXSIZE * MAXSIZE * sizeof(Stack)); stack->top = 0; } //入栈 void InsertStack(SqStack* stack, Stack data) { stack->base[stack->top] = data; stack->top++; printf("arr[%d][%d]成功入栈!n", data.x, data.y); } //出栈 Stack PopStack(SqStack* stack) { stack->top--; printf("arr[%d][%d]成功出栈!n", stack->base[stack->top].x, stack->base[stack->top].y); return stack->base[stack->top]; } //判栈空 int StackEmpty(SqStack* stack) { if (stack->top == 0) { return 1; } else { return 0; } } //取栈顶元素 Stack GetTop(SqStack* stack) { int q = stack->top - 1; return stack->base[q]; } //判断该位置是否为墙和之前是否经过 int CanPass(Stack data) { if (arr[data.x][data.y] == 1 || arr_tar[data.x][data.y] == 1) { return 1; } else { return 0; } } //判断该位置是否为出口 int IsEnd(Stack data) { if (arr[data.x][data.y] == 2) { printf("发现出口!!!n"); return 1; } else { return 0; } } //移动 void move(SqStack* stack) { Stack data = GetTop(stack); Stack new_data; if (data.direction == 1)//东 { printf("向东走了一格n"); new_data.direction = 1; new_data.x = data.x; new_data.y = data.y + 1; } else if (data.direction == 2)//南 { printf("向南走了一格n"); new_data.direction = 1; new_data.x = data.x + 1; new_data.y = data.y; } else if (data.direction == 3)//西 { printf("向西走了一格n"); new_data.direction = 1; new_data.x = data.x; new_data.y = data.y - 1; } else if (data.direction == 4)//北 { printf("向北走了一格n"); new_data.direction = 1; new_data.x = data.x - 1; new_data.y = data.y; } InsertStack(stack, new_data); } //更新走过的路径 void AddPath(Stack data) { arr_tar[data.x][data.y] = 1; } void PopPath(Stack data) { arr_tar[data.x][data.y] = 0; } int main() { SqStack* stack = (SqStack*)malloc(sizeof(SqStack)); //遍历迷宫 int i, j; for (i = 0;i < MAXSIZE; i++) { for (j = 0;j < MAXSIZE; j++) { printf("%dt", arr[i][j]); } printf("n"); } printf("--------------------破译中--------------------n"); //初始化 InitStack(stack); //设置初始点 int x = 1, y = 1; Stack data = {x, y, 1}; InsertStack(stack, data); do { if(!CanPass(GetTop(stack)))//不是墙并且从未走过 { if (IsEnd(GetTop(stack)))//检测出口 { break; } else { AddPath(GetTop(stack)); move(stack);//添加下一个块到栈中 } } else//是墙 { PopStack(stack); PopPath(GetTop(stack));//栈顶元素的路径不算入经过地点 if (!StackEmpty(stack)) { if (GetTop(stack).direction == 4 && !StackEmpty(stack)) { AddPath(GetTop(stack)); PopStack(stack); PopPath(GetTop(stack)); } if (GetTop(stack).direction < 4) { //更新栈顶坐标的方向 stack->base[stack->top - 1].direction++; } } } //getchar(); }while(!StackEmpty(stack)); printf("--------------------破译完毕--------------------n"); //输出结果 while (!StackEmpty(stack)) { data = PopStack(stack); arr[data.x][data.y] = 3; } //遍历迷宫 for (i = 0;i < MAXSIZE; i++) { for (j = 0;j < MAXSIZE; j++) { printf("%dt", arr[i][j]); } printf("n"); } return 0; }
欢迎大家留言交流
结语:这不仅仅是一个算法,你把他加点功能(增删改查),他就变成了期末的课程设计。



