| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3826 人关注过本帖
标题:迷宫问题?
只看楼主 加入收藏
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
我的代码:可能丑陋了点,没办法,现在的水平就只有这样了。
/********************************************************
** Highlight software by yzfy(雨中飞燕) http:// *
*********************************************************/
#include<iostream>
#include<ctime>
using namespace std;
const int m=12,p=15;          //迷宫的行数和列数
struct offsets              //前进方向表的结构定义
{
    int a,b;              //a,b是x,y(SeekPath函数参数)方向的偏移
    char *dir;              //dir是方向
};
            
int Maze[m+2][p+2];       //迷宫定义
int mark[m+2][p+2];      //访问标记数组
//各个方向的偏移表
offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"S"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
int main()
{
    int SeekPath(int,int);
    int i,j;
    srand(unsigned(time(NULL)));
    for(i=0;i<m+2;i++)               //用随机数产生迷宫
    {
        for(j=0;j<=p+1;j++)
            Maze[i][j]=rand()%2;
    }
    //设定行边界
    for(j=0;j<=p+1;j++)
    {
        Maze[0][j]=Maze[m+1][j]=1;
    }
    //设定列边界
    for(i=0;i<=m+1;i++)
    {
        Maze[i][0]=Maze[i][p+1]=1;
    }
    for(i=0;i<m+2;i++)                 //访问标记数组初始为零
        for(j=0;j<p+2;j++)
            mark[i][j]=0;
    cout<<"The maze is:"<<endl;         //输出刚才产生的迷宫
    for(i=0;i<m+2;i++)
    {
        for(j=0;j<p+2;j++)
            cout<<Maze[i][j];
        cout<<endl;
    }
    mark[1][1]=1;                    //从入口[1][1]开始
   
    if(SeekPath(1,1))                //调用求解迷宫的递归算法
        cout<<"("<<1<<","<<1<<"(,"<<"Direction"<<"E"<<endl;
    system("pause");
    return 0;
}
int SeekPath(int x,int y)
{
    //从迷宫某一位置开始,寻找通向出口[M][P]的一条路径。
    //如果找到,返回1,否刚返回0;
    //试探的出发点为[1][1].
    int i,g=0,h=0;                    //用G,H记录位置信息,D记方向
    char *d=NULL;
    if(x==m&&y==p)
        return 1;                     //到达出口,返回1;
    for(i=0;i<8;i++)
    {
        g=x+move[i].a;               
        h=y+move[i].b;
        d=move[i].dir;              //找下一位置和方向(a,b,dir)
        if(Maze[g][h]==0 && mark[g][h]==0)
        {
            mark[g][h]=1;
            if(SeekPath(g,h))              //从此位置递归试探
            {
                cout<<"("<<g<<","<<h<<"),"<<"Direction  "<<d<<endl;
                return 1;                //试探成功,逆向输出路径坐标
            }
        }
    }
    if(x==1&&y==1)
        cout<<"no path in Maze"<<endl;
    return 0;
}

i like linux...
2008-05-06 16:29
雨中飛燕
Rank: 1
等 级:新手上路
帖 子:765
专家分:0
注 册:2007-10-13
收藏
得分:0 
呵呵,赞一个

[color=white]
2008-05-06 16:31
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
非递归解法已出来,由于刚才递归解法中遇到的问题,在飞燕姐的帮肋下,已解决,所以写这个这少了很多麻烦,注意了几个问题,所以只要算法正确,就能写出来了。程序中还有不足之处,以后再优化了,一高兴就先把代码发上来了,呵呵。再次感谢飞燕姐。
这次输出的只是出口,是我自已设定的。为(12,15)。试了几十次,五次成功找到出口。代码如下:
/********************************************************
** Highlight software by yzfy(雨中飞燕) http:// *
*********************************************************/
#include<iostream>
#include<ctime>
#include<stack>
using namespace std;
//前进方向表的结构定义
struct offsets
{
    int a,b;          //a,b是方向的偏移
    char *dir;        //dir是方向
};
//栈中的三元组结构
struct items
{
    int x,y,dir;             //位置和前进方向序号
};
offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"S"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
const int m=12,p=15;
int mark[m+2][p+2];
int Maze[m+2][p+2];
//输出迷宫路径操作的实现
    ostream& operator<<(ostream& os,items& item)
{
    return os<<item.x<<" ,"<<item.y<<" ,"<<item.dir<<endl;
}

int main()
{
    void path(int m,int p);              //寻找出口函数
    srand(unsigned(time(NULL)));
    int i,j;
    //用随机数产生迷宫
    for(i=0;i<m+2;i++)                 
        for(j=0;j<p+2;j++)
            Maze[i][j]=rand()%2;
    //初始化标记数组
    for(i=0;i<m+2;i++)
        for(j=0;j<p+2;j++)
            mark[i][j]=0;
    //设定行边界
    for(j=0;j<p+2;j++)
        Maze[0][j]=Maze[m+1][j]=1;
    //设定列边界
    for(i=0;i<m+2;i++)
        Maze[i][0]=Maze[i][p+1]=1;
    //输出迷宫
    for(i=0;i<m+2;i++)
    {
        for(j=0;j<p+2;j++)
            cout<<Maze[i][j];
        cout<<endl;
    }
    path(m,p);
    system("pause");
    return 0;
}
void path(int m,int p)
{
    int i,j,d,g,h;
    mark[1][0]=1;           //设置入口
    stack<items> st;
    items tmp;
    tmp.x=1;tmp.y=0;tmp.dir=2;
    st.push(tmp);
    //栈不空,持续走下去
    while(st.empty()==false)
    {
        st.pop();              //退栈
        i=tmp.x;j=tmp.y;d=tmp.dir;         //d为前进方向表下标
        while(d<8)
        {
            g=i+move[d].a;h=j+move[d].b; //找下一个位置
            if(g==m&&h==p)                //找到出口
            {
                //cout<<st;
                cout<<m<<"  "<<p<<endl;   //输出出口位置
                return ;
            }
            if(Maze[g][h]==0&&mark[g][h]==0)    //新的路径可通
            {
                mark[g][h]=1;                  //标记为已访问过
                tmp.x=i;
                tmp.y=j;
                tmp.dir=d;
                st.push(tmp);               //进栈
                i=g;j=h;d=0;   //移动到(G,H),在各方向试探
            }
            else
               
d++;           //试探下一个方向
        }
    }
    cout<<"no path in maze!"<<endl;
}


[[it] 本帖最后由 zjl138 于 2008-5-6 16:59 编辑 [/it]]

i like linux...
2008-05-06 16:58
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
收藏
得分:0 
我也写个简单的..固定出入口的非递归算法
#include <stdio.h>
#include <stdlib.h>
#define M    5
#define N    5
void serch_road(int map[][N],int m,int n)
{
    int is[8]={-1,-1,-1, 0,0, 1,1,1};
    int js[8]={-1, 0, 1,-1,1,-1,0,1};
    int stack[3*M*N],*top;
    int i,j,v,g,h,jt;
    top=stack;
    i=j=v=0;
    if(map[0][0]!=0)
    {
        map[0][0]=4;
        printf("1.no path!\n");
        return;
    }
    while(top!=stack||v!=7)
    {   
        g=i+is[v];
        h=j+js[v];
    
        jt=0;
        if(g>-1&&g<m&&h>-1&&h<n)
        {   //printf("%d %d %d\n",g,h,map[g][h]);
            if(g==m-1&&h==n-1&&map[m-1][n-1]==0)
            {
                map[i][j]=8;
                map[g][h]=8;
                return;
            }
            if(map[g][h]==0)
            {
                map[g][h]=4;
                map[i][j]=8;
                top+=3;
                top[0]=i;
                top[1]=j;
                top[2]=v;
                i=g;
                j=h;
                v=0;
                jt=1;
            }
        }
        if(jt==0)
        {
            if(v<7) v++;
            else
            {
                while(top!=stack&&top[2]==7)
                {    map[top[0]][top[1]]=4;
                    top-=3;
                }
            
                if(top!=stack)
                {
                i=top[0];
                j=top[1];
                v=top[2];
                map[i][j]=4;
                top-=3;
                }
            }
        }
    }
    printf("2.no path! \n");
    return;
}
int main()
{
       int i,j;
    int map[M][N]={    {0,1,1,1,1},
                    {0,1,1,0,1},
                    {0,0,0,1,1},
                    {0,1,0,0,1},
                    {0,0,1,1,0}};

    serch_road(map,M,N);
    for(i=0;i<M;i++)
    {
        for(j=0;j<N;j++)
            printf("%d ",map[i][j]);
        printf("\n");
    }
    getchar();
    return 0;
}

学习需要安静。。海盗要重新来过。。
2008-05-06 17:03
雨中飛燕
Rank: 1
等 级:新手上路
帖 子:765
专家分:0
注 册:2007-10-13
收藏
得分:0 
自己写一个栈来模拟递归仅仅是表面上不是递归而已,核心仍然不变
真正非递归干脆换成BFS吧

[color=white]
2008-05-06 17:06
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
这样子啊,刚学了BFS还没练习过,有时间再来试一下吧。用队列可以找一条到达迷宫出口的最短路径(如果存在)这个算不算真正意义上的非递归呢?

i like linux...
2008-05-06 19:23
雨中飛燕
Rank: 1
等 级:新手上路
帖 子:765
专家分:0
注 册:2007-10-13
收藏
得分:0 
算法本身是非递归形式的话,估计你也不可能硬写成递归吧

[color=white]
2008-05-06 19:40
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
收藏
得分:0 
燕子我发觉你都很少休息..呵呵..zjl138兄弟,我下午在看书,过几天要考试..uml都很糊涂呢,看见你在写,所以就弄个简单的,谁知道你后来弄好了...呵呵

[[it] 本帖最后由 sunkaidong 于 2008-5-6 19:51 编辑 [/it]]

学习需要安静。。海盗要重新来过。。
2008-05-06 19:45
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
呵呵,是的。我要学的还很多,慢慢来了,没办法。我试过急了,结果更慢。

i like linux...
2008-05-06 19:48
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
[bo]以下是引用 [un]sunkaidong[/un] 在 2008-5-6 19:45 的发言:[/bo]

燕子我发觉你都很少休息..呵呵..zjl138兄弟,我下午在看书,过几天要考试..uml都很糊涂呢,看见你在写,所以就弄个简单的,谁知道你后来弄好了...呵呵


谢谢suikaidong兄了,这么忙还帮我。对了,差不多软考了哦,复习得还好吧。听师兄说软件考UML是必考的,还占有一定的分数。我也不大清楚,现在还没有去考软设的欲望,只想把算法学好。
sunkaidong兄:Good luck!

i like linux...
2008-05-06 20:13
快速回复:迷宫问题?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024024 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved