XMU C语言程序设计实践(3)
问题描述:
以一个n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍,设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
对于本问题需用栈实现“穷举求解”算法,即:从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。加入所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。迷宫数据是一个n阶矩阵用二维数组存储,起点为(1,1),终点为(n,n),再在迷宫外围加上一层围墙(默认为1,不需用户输入,用户只需输入迷宫数据即可),对于迷宫中每个数据都有四个方向可通。
具体实现算法的函数及要点如下:初始化栈,销毁栈,清空栈,判栈空,取栈顶元素,插入新的栈顶元素,删除栈顶元素,从栈底到栈顶依次访问栈中的每个结点,最重要的就是要判断迷宫的通路。
从迷宫的入口到出口找出一条通路的算法如下:
设定当前位置的初值为入口位置;
Do
{
若当前位置可通,
则
{
将当前位置插入栈顶;
若该位置是出口位置,则算法结束;
否则切换当前位置的东邻方块为新的位置;
}
否则
{
回到当前位置的前一个位置,判断是否可通(类似于上面算法)
……
}
}while(栈不空);
若栈不空且栈顶位置尚有其他方向未被探索,
则设定新的当前位置为: 沿顺时针方向旋转
找到的栈顶位置的下一相邻块;
若栈不空但栈顶位置的四周均不可通,
则
{
删去栈顶位置;// 从路径中删去该通道块
若栈不空,则重新测试新的栈顶位置,
直至找到一个可通的相邻块或出栈至栈空;
}
若栈空,则表明迷宫通路。
最后根据栈储存的数据输出迷宫径即可。
递归:
1 // 2 //by coolxxx 3 // 4 #include<stdio.h> 5 #include<stdlib.h> 6 #include<string.h> 7 #define max(a,b) ((a)>(b)?(a):(b)) 8 #define min(a,b) ((a)<(b)?(a):(b)) 9 #define abs(a) ((a)>0?(a):(-(a))) 10 #define sqr(a) ((a)*(a)) 11 #define swap(a,b) (a)^=(b),(b)^=(a),(a)^=(b) 12 #define eps 1e-8 13 #define MAX 0x7f7f7f7f 14 #define N 1004 15 #define M 1000004 16 char map[N][N]; 17 int u[N][N]; 18 int n,m,ans,lll; 19 int dx[]={-1,1,0,0}; 20 int dy[]={0,0,-1,1}; 21 int a[M][2]; 22 void pop() 23 { 24 a[lll][0]=a[lll][1]=0; 25 lll--; 26 } 27 void push(int x,int y) 28 { 29 a[++lll][0]=x; 30 a[lll][1]=y; 31 } 32 void gettop(int *x,int *y) 33 { 34 *x=a[lll][0]; 35 *y=a[lll][1]; 36 } 37 int uempty() 38 { 39 return lll; 40 } 41 void init() 42 { 43 int i; 44 memset(a,0,sizeof(a)); 45 memset(u,0,sizeof(u)); 46 lll=0; 47 } 48 int dfs(int x,int y) 49 { 50 if(x==n && y==n && map[x][y]=='0') 51 return 1; 52 int i,j,xx,yy; 53 u[x][y]=1; 54 for(i=0;i<4;i++) 55 { 56 xx=x+dx[i]; 57 yy=y+dy[i]; 58 if(xx<1 || yy<1 || xx>n || yy>n || map[xx][yy]=='1' || u[xx][yy])continue; 59 j=dfs(xx,yy); 60 if(j) 61 { 62 push(xx,yy); 63 return 1; 64 } 65 } 66 return 0; 67 } 68 int main() 69 { 70 freopen("1.txt","r",stdin); 71 int i,j; 72 scanf("%d",&n); 73 for(i=1;i<=n;i++) 74 { 75 scanf("%s",map[i]+1); 76 puts(map[i]+1); 77 } 78 if(map[1][1]=='1'){puts("No way");return 0;} 79 init(); 80 if(dfs(1,1)) 81 { 82 push(1,1); 83 for(i=lll;i>1;i--) 84 printf("(%d,%d)->",a[i][0],a[i][1]); 85 printf("(%d,%d)\n",n,n); 86 } 87 else 88 { 89 puts("No way"); 90 } 91 return 0; 92 } 93 /* 94 95 */
非递归:
1 // 2 //by coolxxx 3 // 4 #include<stdio.h> 5 #include<stdlib.h> 6 #include<string.h> 7 #define max(a,b) ((a)>(b)?(a):(b)) 8 #define min(a,b) ((a)<(b)?(a):(b)) 9 #define abs(a) ((a)>0?(a):(-(a))) 10 #define sqr(a) ((a)*(a)) 11 #define swap(a,b) (a)^=(b),(b)^=(a),(a)^=(b) 12 #define eps 1e-8 13 #define MAX 0x7f7f7f7f 14 #define N 1004 15 #define M 1000004 16 char map[N][N]; 17 int u[N][N]; 18 int n,m,ans,lll; 19 int dx[]={-1,1,0,0}; 20 int dy[]={0,0,-1,1}; 21 int a[M][2]; 22 void pop() 23 { 24 a[lll][0]=a[lll][1]=0; 25 lll--; 26 } 27 void push(int x,int y) 28 { 29 a[++lll][0]=x; 30 a[lll][1]=y; 31 } 32 void gettop(int *x,int *y) 33 { 34 *x=a[lll][0]; 35 *y=a[lll][1]; 36 } 37 int uempty() 38 { 39 return lll; 40 } 41 void init() 42 { 43 int i; 44 memset(a,0,sizeof(a)); 45 memset(u,0,sizeof(u)); 46 lll=0; 47 } 48 void print() 49 { 50 int i,j; 51 for(i=1;i<lll;i++) 52 printf("(%d,%d)->",a[i][0],a[i][1]); 53 printf("(%d,%d)\n",n,n); 54 } 55 void dfs() 56 { 57 int i,j,x,y,xx,yy; 58 gettop(&x,&y); 59 if(x==n && y==n && map[x][y]=='0') 60 { 61 print(); 62 exit(0); 63 } 64 for(i=0;i<4;i++) 65 { 66 xx=x+dx[i]; 67 yy=y+dy[i]; 68 if(xx<1 || yy<1 || xx>n || yy>n || map[xx][yy]=='1' || u[xx][yy])continue; 69 push(xx,yy); 70 u[xx][yy]=1; 71 dfs(); 72 pop(xx,yy); 73 } 74 } 75 int main() 76 { 77 freopen("1.txt","r",stdin); 78 int i,j; 79 scanf("%d",&n); 80 for(i=1;i<=n;i++) 81 { 82 scanf("%s",map[i]+1); 83 puts(map[i]+1); 84 } 85 if(map[1][1]=='1'){puts("No way");return 0;} 86 push(1,1); 87 dfs(1,1); 88 puts("No way"); 89 return 0; 90 } 91 /* 92 93 */