迷宫问题

来源:互联网 发布:怎么删除kingroot软件 编辑:程序博客网 时间:2024/06/06 12:52

问题描述:

迷宫实验是取自心理学的一个古典实验。在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒子中设置了许多墙,对行进方向形成了多处阻挡。盒子仅有一个出口,在出口处放置一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口。对同一只老鼠重复进行上述实验,一直到老鼠从入口到出口,而不走错一步。老鼠经过多次试验终于得到它学习走通迷宫的路线。设计一个计算机程序对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

题目要求:

利用一个二维数组mg[x][y]表示迷宫,其中1<=x<=n,1<=y<=m。数组元素值为1表示该位置是墙壁,不能通行;元素值为0表示该位置是通路。假定从mg[1][1]出发,出口位于mg[n][m],移动方向可以是8个方向(东,东南,南,西南,西,西北,北和东北)。用一种标志(如数字8)在二维数组中标出该条通路,并在屏幕上输出二维数组。

解题思路:

   可以用顺序栈来解决,定义一个栈的数组,如果觉得开数组会有空间浪费也可以用malloc()函数临时分配,因为这个问题只是一次作业所以就偷个懒。可以在开始的时候定义一个数判断迷宫是不是有通路,然后在迷宫输入后先把入口进栈,然后依次搜寻入口的八个方位,如果找到一个方位是通路就接着进栈,为了防止下一个通路寻找时返回到了之前经过的地方,还需要将数组内该位置的数设置为-1,然后接着寻找通路,如果还能找到可以进栈的通路则接着进栈,如果没有则退栈,并且将该位置的数组的值改为0,表示这个位置可以作为其他路径的通路,如果最后一个进栈的是出口,则表示这个迷宫有至少一条通路,因为题目要求只需要一条通路就可以了,所以直接跳出循环,并且将判断是否有通路的值进行改变,最后栈里面保存的就是迷宫的路径,然后进行输出,反之,如果最后一个进栈的不是出口则表示迷宫没有出口,输出没有通路。   这个代码有一个限制就是入口跟出口默认是0,如果认为入口和出口可以被堵死的话还可以加一个判断,我这里没有加,如果想入口跟出口不固定自己设置的话也可以改一下,将函数调用的时候的数修改成自己想要的就可以了,自己想怎么改就怎么改,我只贴一个没有优化的代码。

题目代码:

#include<stdio.h>struct{    int i;    int j;    int di;}Stack[1000];//定义栈的数组int top = -1;//栈顶指针 void mgpath(int xi,int yi,int xe,int ye){    int x,y;    int mg[100][100];    printf("请输入迷宫示意图,1代表障碍物,0代表通路\n");    printf("认为第一个数为入口,最后一个数为出口,生成迷宫时请将入口和出口设置为0\n");    for(x = 1; x <= xe; x++)    {        for(y = 1; y <= ye; y++)        {            scanf("%d",&mg[x][y]);        }    }    for(x = 0; x < xe+2; x++)    {        for(y = 0; y < ye+2; y++)        {            mg[0][y] = 1;            mg[x][0] = 1;            mg[x][ye+1] = 1;            mg[xe+1][y] = 1;        }    }    printf("生成迷宫样式为\n");    for(x = 0; x < xe+2; x++)    {        for(y = 0; y < ye+2; y++)        {            printf("%d ",mg[x][y]);        }        printf("\n");    }    int i,j,di,find,k;    int a = 0;//判断是否有出路     top++;//进栈    Stack[top].i = xi;    Stack[top].j = yi;    Stack[top].di = -1;    mg[xi][yi] = -1; //初始方块进栈    while(top>-1)    {        if(i==xe&&j==ye)//找到出口,输出路径         {            printf("迷宫的其中一条路径为:\n");                for(x = 0; x < xe+2; x++)            {                for(y = 0; y < ye+2; y++)                {                    for(k = 0; k <= top; k++)                    {                        if(x==Stack[k].i&&y==Stack[k].j)                        {                            mg[x][y] = 8;                            break;                        }                    }                }            }            for(x = 0; x < xe+2; x++)            {                for(y = 0; y < ye+2; y++)                {                    printf("%d ",mg[x][y]);                }                printf("\n");            }            a=1;            break;        }        i = Stack[top].i;        j = Stack[top].j;        di = Stack[top].di;        find = 0;        while(di < 8&&find==0) //找下一个可走方块         {            di++;            switch(di)            {                case 0:i = Stack[top].i-1; j = Stack[top].j; break;                case 1:i = Stack[top].i; j = Stack[top].j+1; break;                case 2:i = Stack[top].i+1; j = Stack[top].j; break;                case 3:i = Stack[top].i; j = Stack[top].j-1; break;                case 4:i = Stack[top].i+1; j = Stack[top].j-1; break;                case 5:i = Stack[top].i-1; j = Stack[top].j-1; break;                case 6:i = Stack[top].i-1; j = Stack[top].j+1; break;                case 7:i = Stack[top].i+1; j = Stack[top].j+1; break;            }            if(mg[i][j]==0) find = 1;        }         if(find==1)        {            Stack[top].di = di;//找到下一个可走方块,修改栈顶元素的di值             top++;            Stack[top].i = i;            Stack[top].j = j;            Stack[top].di = -1;//下一个可走节点进栈            mg[i][j] = -1;//避免重复走到该方块         }        else        {            mg[Stack[top].i][Stack[top].j] = 0;//没有路径可走则退栈,将该位置变为其他路径可走方块             top--;        }       }    if(a==0)    {        printf("该迷宫没有通路\n");     }   }int main (void){    int n,m;    printf("请输入迷宫大小(第一位数为迷宫长度,第二位为宽度):\n");    scanf("%d%d",&n,&m);    mgpath(1,1,n,m);    return 0;}
原创粉丝点击