电子老鼠闯迷宫(广搜_队列)_机器寻径引导(最短路径表)
时限:1000ms 内存限制:10000K 总时限:3000ms
描述:
有一只电子老鼠被困在如下图所示的迷宫中。这是一个12*12单元的正方形迷宫,黑色部分表示建筑物,白色部分是路。 电子老鼠可以在路上向上、下、左、右行走,每一步走一个格子。现给定一个起点S和一个终点T,求出电子老鼠最少 要几步从起点走到终点。
输入:
本题包含一个测例。在测例的第一行有四个由空格分隔的整数,分别表示起点的坐标S(x.y)和终点的坐标T(x,y)。 从第二行开始的12行中,每行有12个字符,描述迷宫的情况,其中'X'表示建筑物,'.'表示路.
输出:
输出一个整数,即电子老鼠走出迷宫至少需要的步数。
输入样例:
2 9 11 8 XXXXXXXXXXXX X......X.XXX X.X.XX.....X X.X.XX.XXX.X X.X.....X..X X.XXXXXXXX.X X...X.X....X X.XXX...XXXX X.....X....X XXX.XXXX.X.X XXXXXXX..XXX XXXXXXXXXXXX
输出样例:
28
#include<stdio.h> void readdata(); void init(); int search(); bool empty_queue(); void addto_queue(int row,int col); int takeout_queue(); bool canmoveto(int row,int col,int *r,int *c,int i); bool isaim(int row,int col); #define N 12 char Array[12][12]; int beginrow,begincol,endrow,endcol; int head,tail,queue[1000],queue_len=1000;//广搜,使用队列 int main() { int i,j; int step_num; readdata(); init(); //////输出初始状态 printf("初始状态:\n"); for(i=0;i<N;i++) { for(j=0;j<N;j++) { printf("%2c",Array[i][j]); } printf("\n"); } ////// step_num=search(); printf("结束状态:\n"); for(i=0;i<N;i++)//输出搜索之后的状态 { for(j=0;j<N;j++) { if(Array[i][j]=='*' ||Array[i][j]=='.') printf("%3c",Array[i][j]);//char[][]既可用%c输出(字符) else printf("%3d",Array[i][j]-48);//也可用%d输出(数字) } printf("\n"); } printf("%d\n",step_num); return 0; } ////////////////////////////////////////////// int search() { int i; int u,row,col,r,c; int num; while(!empty_queue()) { u=takeout_queue(); row=u/N; col=u%N; num=Array[row][col]-48;//字符到数字(路径长) for(i=0;i<4;i++)//四个方向,广搜 { if(canmoveto(row,col,&r,&c,i)) { if(isaim(r,c)) return num+1;//返回最短路径长度 Array[r][c]=(num+48)+1;//(路径长)数字到字符(Array[][]是字符数组) addto_queue(r,c); } } } return 0; } bool empty_queue() { if(head==tail) return true; return false; } int takeout_queue() { int u; u=queue[head++]; head=head%queue_len; return u; } bool canmoveto(int row,int col,int *r,int *c,int i)//判断能否由当前位置有方向i移动到下一位置 { int PresentRow=row; int PresentCol=col; switch(i) { case 0: col--; break;//左 case 1: row++; break;//下 case 2: col++; break;//右 case 3: row--; break;//上 } *r=row; *c=col; if(row>=0 &&col>=0 &&row<N &&col<N) if(Array[row][col]=='.' ||Array[*r][*c]>Array[PresentRow][PresentCol]+1)//该点未走过,或有更短路径过该点 return true; return false; } bool isaim(int r,int c) { if(r==endrow-1 &&c==endcol-1) return true; return false; } void addto_queue(int row,int col) { int u; u=row*N+col; queue[tail++]=u; tail=tail%queue_len; } ////////////////////////////////////////////// void readdata() { int i,j; char str[12]; scanf("%d%d",&beginrow,&begincol);//起点坐标 scanf("%d%d",&endrow,&endcol);//终点点坐标 for(i=0;i<N;i++) { scanf("%s",str);//迷宫布局 //gets(str); for(j=0;j<N;j++) { if(str[j]=='.') Array[i][j]='.'; else Array[i][j]='*'; } } } void init() { head=0; tail=1; queue[0]=beginrow*N +begincol;//队列初始情况(queue中元素值在区间0~11*12+11之间) Array[beginrow][begincol]=0+48;//初始位置置'0' } /* 2 9 11 8 XXXXXXXXXXXX X......X.XXX X.X.XX.....X X.X.XX.XXX.X X.X.....X..X X.XXXXXXXX.X X...X.X....X X.XXX...XXXX X.....X....X XXX.XXXX.X.X XXXXXXX..XXX XXXXXXXXXXXX 初始状态: * * * * * * * * * * * * * . . . . . . * . * * * * . * . * * . . . 0 . * * . * . * * . * * * . * * . * . . . . . * . . * * . * * * * * * * * . * * . . . * . * . . . . * * . * * * . . . * * * * * . . . . . * . . . . * * * * . * * * * . * . * * * * * * * * . . * * * * * * * * * * * * * * * 结束状态: * * * * * * * * * * * * * 9 8 7 6 5 4 * 2 * * * * 10 * 8 * * 3 2 1 0 1 * * 11 * 9 * * 4 * * * 2 * * 12 * 8 7 6 5 6 * 4 3 * * 13 * * * * * * * * 4 * * 14 . . * 12 * 8 7 6 5 * * . * * * 11 10 9 * * * * * . . 14 13 12 * 10 11 12 13 * * * * . * * * * 12 * . * * * * * * * * . 13 * * * * * * * * * * * * * * * 14 Press any key to continue */