C的迷宫问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C的迷宫问题相关的知识,希望对你有一定的参考价值。
要求编写queue.h,maze.c,queue.c
这里有部分maze.c:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#define MAX_ROWS 300
#define MAX_COLS 300
int main(void)
return 0;
这是迷宫图:
21 21
*********************
* * *
* ******* *** * *** *
* * * * * *
***** * ********* * *
* * * * * *
* * *** * *** *******
* * * * * *
* ******* * ******* *
* * * * *
* ********* * * * * *
* * * * * * *
*** *** * *** * *** *
* * * * * *
* ******* * *** * ***
* * * * * *
* *** * ********* * *
* * * * * * *
* ********* * * *** *
* * * *
*********************
只要从左上角,到右下角,不需要入口和出口
(谁作出来再给30分)
只要求读迷宫,画路,不要画迷宫(迷宫如图所给).
整个顺序为先queue.h,然后maze.c.当跑maze.c的时候,自动跳到queue.c(所有有关函数的文件),再回到maze.c,整个maze.c完了,路也就自然而然出现了.(一定要有路,也就是说怎么跑的)
那个迷宫图"*"代表墙," "(空格)代表路.
老师说降低难度,所以不用入口和出口.
7. 迷宫问题
给一个20×20的迷宫、起点坐标和终点坐标,问从起点是否能到达终点。
输入数据:’.’表示空格;’X’表示墙。
程序如下:
#include <stdio.h>
#include <math.h>
void search(int,int);
int canplace(int,int);
void readdata(); //读入数据
void printresult(); //打印结果
int a[20][20]; //a数组存放迷宫
int s,t;
int main()
int row, col;
readdata();
row=s/20;
col=s%20;
search(row,col); //递归搜索
printresult();
void search(int row, int col)
int r,c;
a[row][col]=1;
r=row; //左
c=col-1;
if(canplace(r,c)) //判断(r,c)位置是否已经走过
search(r,c); //递归搜索(r,c)
r=row+1; //下
c=col;
if(canplace(r,c)) //判断(r,c)位置是否已经走过
search(r,c); //递归搜索(r,c)
r=row; //右
c=col+1;
if(canplace(r,c)) //判断(r,c)位置是否已经走过
search(r,c); //递归搜索(r,c)
r=row-1; //上
c=col;
if(canplace(r,c)) //判断(r,c)位置是否已经走过
search(r,c); //递归搜索(r,c)
void printresult()
int i,j;
for(i=0;i<20;i++)
for(j=0;j<20;j++)
printf("%3d",a[i][j]);
printf("\n");
void readdata()
int i,j;
for(i=0;i<20;i++)
for(j=0;j<20;j++)
scanf("%d",&a[i][j]);
int canplace(int row, int col)
if(row>=0&&row<20&&col>=0&&col<20&&a[row][col]==0)
return 1;
else
return 0;
2.搜索算法
如下图12×12方格图,找出一条自入口(2,9)到出口(11,8)的最短路径。
抱歉,图案粘贴不上
本题给出完整的程序和一组测试数据。状态:老鼠所在的行、列。程序如下:
#include<stdio.h>
void readdata(); //读入数据
void init(); //初始化
int search(); //广搜,并在每一个可到达的每一个空格出填上最小步数
int emptyopen(); //判栈是否为空:空:1;非空:0。
int takeoutofopen(); //从栈中取出一个元素,并把该元素从栈中删除
int canmoveto(int,int,int*,int*,int); //判能否移动到该方向,并带回坐标(r,c)
int isaim(int row, int col); //判断该点是否是目标
int used(int,int); //判断该点是否已经走过
void addtoopen(int,int); //把该点加入到open表
int a[12][12]; //a存放迷宫,0表示空格,-2表示墙。
//广搜时,未找到目标以前到达的空格,填上到达该点的最小步数
int n; //n为迷宫边长,注:若大于12,必须修改一些参数,如a的大小
int open[20],head,tail,openlen=20; //open表
int s,t; //起点和终点
int main()
int number;
readdata(); //读取数据
init(); //初始化
number=search(); //广搜并返回最小步数
printf("%d",number); //打印结果
int search()
int u, row, col, r, c, i, num;
while(!emptyopen()) //当栈非空
u=takeoutofopen(); //从栈中取出一个元素,并把该元素从栈中删除
row=u/n; //计算该点的坐标
col=u%n;
num=a[row][col]; //取得该点的步数
for(i=0;i<4;i++)
if(canmoveto(row,col,&r,&c,i)) //判能否移动到该方向,并带回坐标(r,c)
if(isaim(r,c)) //如果是目标结点
return(num+1); //返回最小步数
if(!used(r,c)) //如果(r,c)还未到达过
a[r][c]=num+1; //记录该点的最小步数
addtoopen(r,c); //把该点加入到open表
int emptyopen()
if(head==tail)
return(1);
else
return(0);
int takeoutofopen()
int u;
if(head==tail)
printf("errer: stack is empty");
return(-1);
u=open[head++];
head=head%openlen;
return(u);
int canmoveto(int row, int col, int *p, int *q, int direction)
int r,c;
r=row;
c=col;
switch(direction)
case 0: c--; //左
break;
case 1: r++; //下
break;
case 2: c++; //右
break;
case 3: r--; //上
*p=r;
*q=c;
if(r<0||r>=n||c<0||c>=n) //如果越界返回0
return(0);
if(a[r][c]==0) //如果是空格返回1
return(1);
return(0); //其余情况返回0
int isaim(int row, int col)
if(row*n+col==t)
return(1);
else
return(0);
int used(int row, int col)
if(a[row][col]==0) // 0表示空格
return(0);
else
return(1);
void addtoopen(int row, int col)
int u;
u=row*n+col;
open[tail++]= u;
tail=tail%openlen;
void readdata()
int i,j,row,col;
char str[20];
scanf("%d",&n);
scanf("%d%d",&row,&col); //起点坐标
s=row*n+col;
scanf("%d%d",&row,&col); //终点坐标
t=row*n+col;
gets(str);
for(i=0;i<n;i++)
gets(str);
for(j=0;j<n;j++)
if(str[j]=='.')
a[i][j]=0; //0表示空格
else
a[i][j]=-2; //-2表示墙
void init()
head=0;
tail=1;
open[0]=s;
测试数据如下:
12 10 7 1 8
XXXXXXXXXXXX
X......X.XXX
X.X.XX.....X
X.X.XX.XXX.X
X.X.....X..X
X.XXXXXXXXXX
X...X.X....X
X.XXX...XXXX
X.....X....X
XXX.XXXX.X.X
XXXXXXX..XXX
XXXXXXXXXXXX 参考技术B 我不懂你啥要求,你的图我也看不懂,也不知道你什么编译器,我刚才学习栈的时候写了一个,就给你了,如果你也这么做的话,把你的图改成点阵,并且把多设一个外圈,把最外一层置为1,如果你要做界面的话,我不会我就会dos的你自己改:
#include<stdio.h>
#define M 1000 //栈的容量
struct stack
int top; //栈顶
int path[M][2]; //栈的数据
;
struct position //坐标
int x;
int y;
;
int isOnlyOne(struct stack *p); //判断栈是只剩下一个元素
void push(struct stack *p,int x,int y); //将x,y压入栈
void pop(struct stack *p); //出栈
void display(struct stack *p); //遍历栈
int findPath(int (*a)[10],struct stack *p); //判断路径
int east(struct position temp,int (*a)[10]); //返回当前位置东边的值
int sorth(struct position temp,int (*a)[10]); //返回当前位置南边的值
int west(struct position temp,int (*a)[10]); //返回当前位置西边的值
int north(struct position temp,int (*a)[10]); //返回当前位置北边的值
void moveEast(struct position *p); //向东方移动
void moveSorth(struct position *p); //向南方移动
void moveWest(struct position *p); //向西方移动
void moveNorth(struct position *p); //向北方移动
void main()
struct stack st;
struct stack *p=&st; //定义一个栈的指针
int a[10][10]=1,1,1,1,1,1,1,1,1,1, //创建一个迷宫原型
1,0,0,1,0,0,0,1,0,1, //为方便起见,外圈设为1
1,1,0,1,0,0,0,1,0,1, //0代表有路,1代表障碍物
1,0,0,0,1,1,1,0,0,1, //a[1][1]为入口
1,1,1,0,0,0,0,0,1,1, //a[8][8]为出口
1,0,0,0,1,0,1,0,1,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,1,0,1,
1,1,1,1,1,1,1,1,1,1;
p->top=0; //栈顶初始化为0
if(findPath(a,p)==1) //找到一条路径
printf("找到了一条路径:\n");
display(p); //遍历栈输出沿路的坐标
else //没有路
printf("找不到路径\n");
int isOnlyOne(struct stack *p) //判断栈是否就剩一个元素
if(p->top==1)
return 1;
else
return 0;
void push(struct stack *p,int x,int y) //将x,y压入栈,栈顶指针上移动
p->path[p->top][0]=x;
p->path[p->top][1]=y;
p->top++;
void pop(struct stack *p) //出栈,栈顶指针下移
p->top--;
void display(struct stack *p) //遍历栈
int i;
for(i=0;i<p->top;i++)
printf("x:%d\ty:%d\n",p->path[i][0],p->path[i][1]);
int east(struct position temp,int (*a)[10]) //返回当前位置东边的值
temp.x++;
return a[temp.x][temp.y];
int sorth(struct position temp,int (*a)[10]) //返回当前位置南边的值
temp.y++;
return a[temp.x][temp.y];
int west(struct position temp,int (*a)[10]) //返回当前位置西边的值
temp.x--;
return a[temp.x][temp.y];
int north(struct position temp,int (*a)[10]) //返回当前位置北边的值
temp.y--;
return a[temp.x][temp.y];
void moveEast(struct position *p) //向东方移动
p->x++;
void moveSorth(struct position *p) //向南方移动
p->y++;
void moveWest(struct position *p) //向西方移动
p->x--;
void moveNorth(struct position *p) //向北方移动
p->y--;
int findPath(int (*a)[10],struct stack *p) //寻找路径
struct position temp;
temp.x=temp.y=1; //迷宫入口(1,1)
a[1][1]=1; //将迷宫入口封死
while(temp.x!=8||temp.y!=8) //(8,8)时为出口退出循环
if(east(temp,a)==0) //东边有路
push(p,temp.x,temp.y); //将当前坐标存入栈
moveEast(&temp); //向东移动
a[temp.x][temp.y]=1; //将移动后位置封死防止再次移动到这里
else if(sorth(temp,a)==0) //南边有路
push(p,temp.x,temp.y);
moveSorth(&temp);
a[temp.x][temp.y]=1;
else if(west(temp,a)==0) //西边有路
push(p,temp.x,temp.y);
moveWest(&temp);
a[temp.x][temp.y]=1;
else if(north(temp,a)==0) //北边有路
push(p,temp.x,temp.y);
moveNorth(&temp);
a[temp.x][temp.y]=1;
else //东西南北都没路
if(!isOnlyOne(p))
pop(p); //出栈
temp.x=p->path[p->top-1][0]; //将当前栈顶坐标赋值给x,y
temp.y=p->path[p->top-1][1];
else //只剩下栈的入口了
return 0; //不存在路径
return 1;
本回答被提问者采纳 参考技术C 不懂
C语言 栈 迷宫 的一个疑问
if(Pass(curpos))
...
Push(S,e);
...
if(!StackEmpty(S))
Pop(S,e); curstep--;
...
如果下一步 未通过pass函数
即是未入栈,为何还要出栈,这样不是让上一个入的栈出栈了吗?
求高手解答,谢谢!
所以就出栈,这是回溯法啊。
当前入栈的位置是到达不了终点的,所以就出栈。返回上一位置,寻找不同路径。本回答被提问者采纳 参考技术B 是这样的
如果Pass返回值=false 代表不通过,则需要退一格 也就是退栈一次pop(),再判断Pass
不知道你的问题在哪里追问
可既然未通过,那么就不会执行NextPos函数了,就是在原地保持不动啊,退一格不是退回上一个位置了?
追答你的Pass函数只判单方向吗 还是判断该位置是不是死路
贴一些你想问问题的代码段
代码是对的,能实现,但是我对它的实现过程有些不理解
我就是问
当下一个位置不能通过Pass函数时,那么此时栈里面的元素仍然是原来的元素,没有增加。那么进入else,既然未增加元素,为何还要Push?这样不是把上一个元素出栈了吗?
以上是关于C的迷宫问题的主要内容,如果未能解决你的问题,请参考以下文章