一个求迷宫入口到出口最近距离的程序
2012-05-23 16:28
148 查看
本文给出一个c/c++语言版的求迷宫入口到出口的最短路径的程序。程序的大部分使用标准c语言编写,包括
输入和输出。唯一用到C++库的地方是使用STL了中的deque。迷宫的宽和高,迷宫矩阵,迷宫的入口和出口
等数据从文件读入。程序首先读入迷宫数据,然后更新迷宫矩阵,并求出迷宫入口和出口之间的最短路径,
并输出最短路径长度。
1. 迷宫的表示。
迷宫用结构体MATRIX来表示
包括迷宫矩阵,迷宫的宽,迷宫的高,迷宫入口的坐标,迷宫出口的坐标。
结构体定义如下:
typedef struct _step
{
int x; //行坐标
int y; //列坐标
int distance; //距迷宫入口的距离
}STEP;
typedef struct _matrix
{
int data[MAX_WIDTH+2][MAX_WIDTH+2]; //迷宫数据,0:表示有路,1:表示墙
int width; //矩阵(迷宫)的宽,包括最左和最有2堵墙
int height; //矩阵(迷宫)的高,包括顶部和底部2堵墙
STEP entrance; //迷宫入口
STEP exit; //迷宫出口
}MATRIX;
开始时,迷宫矩阵的每一个元素是0或-1,0表示可走,-1表示是墙,走不通。为了便于检查是否越界,
即坐标是否超过迷宫的范围。在迷宫的4个边增加了全-1数据,表示4堵墙。这样,在任何时候,都不
会越界。下面的数据表示1个5×5的迷宫,增加了4堵墙后,实际宽度和高度变为7,迷宫变成1个7×7
的矩阵。在搜索迷宫出口距入口的最近距离的过程中,需要修改矩阵相关元素的值。对所有和迷宫入
口相通的方格,其值被改为其距迷宫入口的最近距离。
-1, -1, -1, -1, -1, -1, -1,
-1, 0, 0, 0, 0, 0, -1,
-1, -1, 0, -1, 0, -1, -1,
-1, 0, 0, -1, -1, -1, -1,
-1, 0, -1, 0, 0, 0, -1,
-1, 0, 0, 0, -1, 0, -1,
-1, -1, -1, -1, -1, -1, -1,
2.算法
迷宫的矩阵的每一方格可用三元组(x,y,d)来表示,x,y表示这个方格的坐标,d表示这个方格距入口
的距离.
1.首先,将入口的坐标(x,y,0),放入双端队列my_queue。
2. 接下来重复以下的过程,直到队列为空
2.1.从队列头部取出一个三元组(x0,y0,d)
2.2.从右,下,左,上四个方向搜索,看能否有非-1的格子
如果可找到一个方格,其坐标为(x,y),且这个方格不是入口点,则有3种情况
case 1.
新方格对应的矩阵元素是0,表明新的方格距迷宫入口的距离尚未标记。
则将新方格对应的矩阵元素设置为d+1,同时将三元组(x,y,d+1)入队
case 2:
新方格的对应的矩阵元素的值>d+1,表明该新方格距迷宫入口的距离已经标记但不是最近的。
则将新方格对应的矩阵元素设置为d+1,同时将三元组(x,y,d+1)入队
case 3:
如果新的方格的对应的矩阵元素<= d+1,该位置距入口的距离已经标记,则不做处理
3.检查出口对应的矩阵元素M[exit.x][exit.y]的值,如果为0,表示没有一条路径可走,否则打印出
口距入口的距离。
全部的代码见下:
输入和输出。唯一用到C++库的地方是使用STL了中的deque。迷宫的宽和高,迷宫矩阵,迷宫的入口和出口
等数据从文件读入。程序首先读入迷宫数据,然后更新迷宫矩阵,并求出迷宫入口和出口之间的最短路径,
并输出最短路径长度。
1. 迷宫的表示。
迷宫用结构体MATRIX来表示
包括迷宫矩阵,迷宫的宽,迷宫的高,迷宫入口的坐标,迷宫出口的坐标。
结构体定义如下:
typedef struct _step
{
int x; //行坐标
int y; //列坐标
int distance; //距迷宫入口的距离
}STEP;
typedef struct _matrix
{
int data[MAX_WIDTH+2][MAX_WIDTH+2]; //迷宫数据,0:表示有路,1:表示墙
int width; //矩阵(迷宫)的宽,包括最左和最有2堵墙
int height; //矩阵(迷宫)的高,包括顶部和底部2堵墙
STEP entrance; //迷宫入口
STEP exit; //迷宫出口
}MATRIX;
开始时,迷宫矩阵的每一个元素是0或-1,0表示可走,-1表示是墙,走不通。为了便于检查是否越界,
即坐标是否超过迷宫的范围。在迷宫的4个边增加了全-1数据,表示4堵墙。这样,在任何时候,都不
会越界。下面的数据表示1个5×5的迷宫,增加了4堵墙后,实际宽度和高度变为7,迷宫变成1个7×7
的矩阵。在搜索迷宫出口距入口的最近距离的过程中,需要修改矩阵相关元素的值。对所有和迷宫入
口相通的方格,其值被改为其距迷宫入口的最近距离。
-1, -1, -1, -1, -1, -1, -1,
-1, 0, 0, 0, 0, 0, -1,
-1, -1, 0, -1, 0, -1, -1,
-1, 0, 0, -1, -1, -1, -1,
-1, 0, -1, 0, 0, 0, -1,
-1, 0, 0, 0, -1, 0, -1,
-1, -1, -1, -1, -1, -1, -1,
2.算法
迷宫的矩阵的每一方格可用三元组(x,y,d)来表示,x,y表示这个方格的坐标,d表示这个方格距入口
的距离.
1.首先,将入口的坐标(x,y,0),放入双端队列my_queue。
2. 接下来重复以下的过程,直到队列为空
2.1.从队列头部取出一个三元组(x0,y0,d)
2.2.从右,下,左,上四个方向搜索,看能否有非-1的格子
如果可找到一个方格,其坐标为(x,y),且这个方格不是入口点,则有3种情况
case 1.
新方格对应的矩阵元素是0,表明新的方格距迷宫入口的距离尚未标记。
则将新方格对应的矩阵元素设置为d+1,同时将三元组(x,y,d+1)入队
case 2:
新方格的对应的矩阵元素的值>d+1,表明该新方格距迷宫入口的距离已经标记但不是最近的。
则将新方格对应的矩阵元素设置为d+1,同时将三元组(x,y,d+1)入队
case 3:
如果新的方格的对应的矩阵元素<= d+1,该位置距入口的距离已经标记,则不做处理
3.检查出口对应的矩阵元素M[exit.x][exit.y]的值,如果为0,表示没有一条路径可走,否则打印出
口距入口的距离。
全部的代码见下:
#include <stdlib.h> #include <stdio.h> #include <memory.h> #include <queue> using namespace std; #define MAX_WIDTH 30 #define MAX_HEIGHT 30 typedef struct _step { int x; //行坐标 int y; //列坐标 int distance; //距迷宫入口的距离 }STEP; typedef struct _matrix { int data[MAX_WIDTH+2][MAX_WIDTH+2]; //迷宫数据,0:表示有路,-1:表示墙 int width; //矩阵(迷宫)的宽,包括最左和最有2堵墙 int height; //矩阵(迷宫)的宽,包括顶部和底部2堵墙 STEP entrance; //迷宫入口 STEP exit; //迷宫出口 }MATRIX; MATRIX g_matrix= //初始化为一个迷宫,程序也能从文件中读入迷宫数据 { { {-1, -1, -1, -1, -1, -1, -1}, {-1, 0, 0, 0, 0, 0, -1}, {-1, -1, 0, -1, 0, -1, -1}, {-1, 0, 0, -1, -1, -1, -1}, {-1, 0, -1, 0, 0, 0, -1}, {-1, 0, 0, 0, -1, 0, -1}, {-1, -1, -1, -1, -1, -1, -1}, }, 7,7, //7行,7列,包括4堵墙 {1,1}, //入口坐标 {5,5} //出口坐标 }; static STEP s_shift[]= { {1,0,0}, //向右走, x++, y 不变 {0,1,0}, //向下走, x 不变, y++ {-1,0,0}, //向左走, x--, y不变 {0,-1,0} //向上走, x 不变, y-- }; void print_Matrix(MATRIX* pMatrix) //打印迷宫数据,迷宫数据包含4堵墙 { int i,j; for (i=0;i<pMatrix->height;i++) { for (j=0;j<pMatrix->width;j++) { if (j!=0) printf(" "); printf("%d",pMatrix->data[i][j]); } printf("\n"); } } int search_min_distance(int matric[MAX_WIDTH+2][MAX_WIDTH+2], STEP entrance, STEP exit) { deque<STEP> my_queue; STEP t1,t2; int i; t1=entrance; t1.distance=0; my_queue.push_back(t1); while ( !my_queue.empty() ) { t1=my_queue.front(); my_queue.pop_front(); t2.distance =t1.distance +1; for (i=0;i<4;i++) { t2.x=t1.x + s_shift[i].x; t2.y=t1.y + s_shift[i].y; if ( (t2.x!=entrance.x || t2.y !=entrance.y) && matric[t2.x][t2.y] != -1 ) { if ( matric[t2.x][t2.y]==0 || matric[t2.x][t2.y]> t2.distance) { matric[t2.x][t2.y]=t2.distance; my_queue.push_back(t2); } } } } return matric[exit.x][exit.y]; } int readMatrix(char *file) { char line[1024]; FILE *fp=NULL; int i,j,x,y; fp=fopen(file,"rt"); if (fp==NULL) { printf("Can not open file %s\n",file); return 0; } memset(&(g_matrix),0,sizeof(g_matrix)); fgets(line,sizeof(line)-1,fp); sscanf(line,"%d %d",&x,&y); //读入迷宫的行数和列数 if ( x>MAX_WIDTH || y>MAX_HEIGHT) { printf("The Matrix is too large\n"); fclose(fp); return 0; } g_matrix.width=x+2; //在4条边增加4堵墙,故宽和高增加2 g_matrix.height=y+2; for (j=0;j<g_matrix.width;j++) { g_matrix.data[0][j]=-1; //第一行为墙 g_matrix.data[g_matrix.height-1][j]=-1; //最后一行为墙 } for (i=0;i<g_matrix.height;i++) { g_matrix.data[i][0]=-1; //最左边的列为墙 g_matrix.data[i][g_matrix.width-1]=-1; //最右边的列为墙 } for (i=1;i<g_matrix.height-1;i++) { char *p; fgets(line,sizeof(line)-1,fp); j=1; p=line; while (1) { while ( *p==' ' || *p== 9 || *p== ',' )//跳过空格和逗号 p++; if ( *p>='0' && *p<='9'|| *p == '-') { sscanf(p,"%d",&(g_matrix.data[i][j])); //读入地i行j列的数据 while ( *p>='0' && *p<='9'|| *p== '-' ) p++; //数据已经读入,跳过当前的数字 j++; } if (j>=g_matrix.width-2) break; } } fgets(line,sizeof(line)-1,fp); //读入入口的行坐标和列坐标,和出口的行坐标,列坐标 sscanf(line,"%d %d %d %d",&(g_matrix.entrance.x),&(g_matrix.exit.y),&(g_matrix.exit.x),&(g_matrix.exit.y)); fclose(fp); fp=NULL; g_matrix.entrance.x++; //增加了一列是墙,故入口横坐标+1 g_matrix.entrance.y++; //增加了一行是墙,故入口纵坐标+1 g_matrix.exit.x++; //增加了一列是墙,故入口横坐标+1 g_matrix.exit.y++; //增加了一列是墙,故入口纵坐标+1 return 1; } int main() { int distance; if ( !readMatrix("matrix.txt") ) //不使用初始化的数据,从文件中读入迷宫数据 { return 0; //读取失败,直接跳出 } printf("The original matrix is\n"); print_Matrix(&g_matrix); distance= search_min_distance(g_matrix.data,g_matrix.entrance,g_matrix.exit); printf("The new matrix is\n"); print_Matrix(&g_matrix); printf("\nThe distance is %d\n",distance); return 0; }
相关文章推荐
- 一个求迷宫入口到出口最近距离的程序 JAVA版本
- [南阳OJ-No.24]素数距离问题|现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度。如果左右有等距离长度素数,则输出左侧的值及相应距离。 如果输入的整数本身就是素
- 素数距离问题 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度。如果左右有等距离长度素数
- 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度。如果左右有等距离长度素数,则输出左侧的值及相应距离。 如果输入的整数本身就是素数,则输出该素数本身,
- 一个简单的mfc单页界面文件读写程序(MFC 程序入口和执行流程)
- 最近写的一个 400电话 管理程序
- 一个app,多个入口图标,activity-alias实现多程序入口并显示指定view完成
- 最近距离 已知平面上的若干点的位置,存入一个List中。现在需要计算所有这些点中,距离最近的两个点间的最小距离。
- 迷宫问题--第一次写的一个算是大点的程序吧……用了接近一天……
- 一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。 复杂度如果是O(n2)则不得分。
- 一个矩阵存储的迷宫地图,可行走的点是0,不可走的点是1,程序输出一条可以行走的路径
- 一个app,多个入口图标,activity-alias实现多程序入口并显示指定view完成
- 已知元素从小到大排列的两个数组x[]和y[],请写出一个程序算出两个数组彼此之间差的绝对值中最小的一个,这叫做数组的距离
- 二叉排序树中,令f = (最大值+最小值) / 2,设计一个算法, 找出距离f值最近、大于f值的结点。复杂度不能为O(n2)。
- 分享一个C#实现的迷宫生成程序,继续演示LINQ语法在C#中的运用
- 小程序的“附近的小程序”是小程序的一个主要流量入口
- 最近写的一个QVOD电影小偷程序
- 一个搜索迷宫出路的程序
- 最近设计了一个生成asp代码的程序,同时也可以作为数据库管理查询的软件,有兴趣的朋友可以去下载!
- 最近做一个SSH项目总结出来的一些程序执行流程