走迷宫问题

走迷宫问题

执行效果图:

 

寻找迷宫出路路径是递归算法中比较经典的问题。下面我将就迷宫的创建,迷宫出路的保存,以及某一迷宫出路的显示进行比较系统性的和大家讲解。

首先我们定义迷宫的大小和迷宫的难度系数(即空格数的比例,当难度系数为0.5时,空格数占0.7;当难度系数为1时,空格数占0.5)。

  #define N 10    //迷宫大小N*N

  #define M 0.8   //难度系数(0.5-1),默认为0.8

迷宫我们用一个二维数组maze[N][N]表示,其中0表示空格,1表示可走通路径,2表示围墙。

然后定义三个数组,其中a[]记录每种方案所需步数,b[]记录最短路径方案号,c[][3]保存所有合法方案图形(借助于稀疏矩阵的思想,其中c[][0]记录横坐标i的位置,c[][1]记录纵坐标j的位置,c[][2]记录的是可通路径)

入口坐标为(1,1),出口坐标为(N-2N-2)。然后定义静态全局标量t来记录临时路径号。定义结构体变量list来记录方案i存储在c[]中的起点和终点。

  typedef struct list  

  { 

    int frist;   //方案i存储在c[]中的起点

    int last;    //方案i存储在c[]中的终点

  }list;

 

创建迷宫:通过随机生成空格坐标来实现迷宫数组的随机化。

 1 void creat_arr(int a[][N])   //创建迷宫数组
 2 {
 3     int i,j,x,y,tem,m=0,k[100];
 4     bool flag;
 5     srand(time(0));
 6     for(i=0;i<N;i++)
 7         for(j=0;j<N;j++)
 8             a[i][j]=2;
 9     for(i=0;i<(N-2)*(N-2)*(0.9-0.4*M);i++)  
10     {
11         flag=false;
12         x=rand()%(N-2)+1;
13         y=rand()%(N-2)+1;
14         tem=x*10+y;
15         for(j=0;j<m;j++)
16         {
17             if(tem==k[j])
18             {
19                 flag=true;
20                 break;
21             }
22         }
23         if(flag)
24         {
25             i--;
26         }
27         else
28         {
29             k[m++]=tem;
30             a[x][y]=0;
31         }
32     }    
33 }

 

保存方案:

 1 void save_arr(int a[][N])  //保存方案
 2 {
 3     int i,j;
 4     for(i=0;i<N;i++)
 5     {
 6         for(j=0;j<N;j++)
 7         {
 8             if(a[i][j]==1)
 9             {
10                 c[s][0]=i;
11                 c[s][1]=j;
12                 c[s++][2]=1;
13                 k++;
14             }
15         }
16     }
17 }

 

绘制图形:

 1 void print(int a[][N])  //绘制图形
 2 {
 3     int m,n;
 4     for(m=0;m<N;m++)
 5     {
 6         for(n=0;n<N;n++)
 7         {
 8             if(a[m][n]==2)
 9                 printf("");
10             else if(a[m][n]==1)
11             {
12                 printf("");
13             }
14             else
15                 printf("");
16         }
17         printf("\n");
18     }
19 }

 

绘制指定方案图形:

1 void print_show(int a[][N],int x,int y)  //绘制指定方案图形
2 {
3     int i;
4     for(i=x;i<y;i++)
5         a[c[i][0]][c[i][1]]=c[i][2];
6     print(a);
7     for(i=x;i<y;i++)      //显示结束后将图案还原成初始状态
8         a[c[i][0]][c[i][1]]=0;
9 }

 

核心代码:显示可通路径

 1 核心代码:显示可通路径
 2 
 3 void visit(int i,int j)  //显示路径
 4 {
 5     maze[i][j]=1;
 6     if(i==endI&&j==endJ)
 7     {
 8         k=0;
 9         printf("路径%d:",++t);
10         save_arr(maze);
11         li[t].frist=s-k;
12         li[t].last=s;
13         printf("共需移动%d步。\n",k);
14         a[t-1]=k;
15     }
16     if(maze[i][j+1]==0)visit(i,j+1);
17     if(maze[i+1][j]==0)visit(i+1,j);
18     if(maze[i][j-1]==0)visit(i,j-1);
19     if(maze[i-1][j]==0)visit(i-1,j);
20     maze[i][j]=0;
21 }


全部执行代码:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<time.h>
  4 
  5 #define N 10    //迷宫大小N*N
  6 #define M 0.8   //难度系数(0.5-1),默认为0.8
  7 static int t=0; //路径号
  8 
  9 int maze[N][N];  //迷宫数组
 10 
 11 int startI=1,startJ=1; // 入口
 12 int endI=N-2,endJ=N-2; // 出口
 13 int a[10000],b[10000],c[100000][3];  //a[]记录每种方案所需步数,b[]记录最短路径方案号,c[]保存所有合法方案图形
 14 int k=0,s=0;  //k步数,s储存所有方案时所用的标记值
 15 
 16 typedef struct list  
 17 { 
 18     int frist;   //方案i存储在c[]中的起点
 19     int last;    //方案i存储在c[]中的终点
 20 }list;
 21 
 22 list li[10000];
 23 
 24 void creat_arr(int a[][N])   //创建迷宫数组
 25 {
 26     int i,j,x,y,tem,m=0,k[100];
 27     bool flag;
 28     srand(time(0));
 29     for(i=0;i<N;i++)
 30         for(j=0;j<N;j++)
 31             a[i][j]=2;
 32     for(i=0;i<(N-2)*(N-2)*(0.9-0.4*M);i++)  //当难度系数为0.5时,空格数占0.7;当难度系数为1时,空格数占0.5
 33     {
 34         flag=false;
 35         x=rand()%(N-2)+1;
 36         y=rand()%(N-2)+1;
 37         tem=x*10+y;
 38         for(j=0;j<m;j++)
 39         {
 40             if(tem==k[j])
 41             {
 42                 flag=true;
 43                 break;
 44             }
 45         }
 46         if(flag)
 47         {
 48             i--;
 49         }
 50         else
 51         {
 52             k[m++]=tem;
 53             a[x][y]=0;
 54         }
 55     }    
 56 }
 57 
 58 void print(int a[][N])  //绘制图形
 59 {
 60     int m,n;
 61     for(m=0;m<N;m++)
 62     {
 63         printf("          ");
 64         for(n=0;n<N;n++)
 65         {
 66             if(a[m][n]==2)
 67                 printf("");
 68             else if(a[m][n]==1)
 69             {
 70                 printf("");
 71             }
 72             else
 73                 printf("");
 74         }
 75         printf("\n");
 76     }
 77 }
 78 
 79 void save_arr(int a[][N])  //保存方案
 80 {
 81     int i,j;
 82     for(i=0;i<N;i++)
 83     {
 84         for(j=0;j<N;j++)
 85         {
 86             if(a[i][j]==1)
 87             {
 88                 c[s][0]=i;
 89                 c[s][1]=j;
 90                 c[s++][2]=1;
 91                 k++;
 92             }
 93         }
 94     }
 95 }
 96 
 97 void print_show(int a[][N],int x,int y)  //绘制指定方案图形
 98 {
 99     int i;
100     for(i=x;i<y;i++)
101         a[c[i][0]][c[i][1]]=c[i][2];
102     print(a);
103     for(i=x;i<y;i++)      //显示结束后将图案还原成初始状态
104         a[c[i][0]][c[i][1]]=0;
105 }
106 
107 void visit(int i,int j)  //显示路径
108 {
109     maze[i][j]=1;
110     if(i==endI&&j==endJ)
111     {
112         k=0;
113         printf("路径%d:",++t);
114         save_arr(maze);
115         li[t].frist=s-k;
116         li[t].last=s;
117         printf("共需移动%d步。\n",k);
118         a[t-1]=k;
119     }
120     if(maze[i][j+1]==0)visit(i,j+1);
121     if(maze[i+1][j]==0)visit(i+1,j);
122     if(maze[i][j-1]==0)visit(i,j-1);
123     if(maze[i-1][j]==0)visit(i-1,j);
124     maze[i][j]=0;
125 }
126 
127 int main(void)
128 {
129     int i,j,min,lu=0,mini=0,isok;
130     bool flag=true;
131     li[0].frist=0;
132     li[0].last=0;
133     printf("\n显示路径:");
134     printf("\n\n-----------------------------------------\n");
135     while(t==0)
136     {
137         creat_arr(maze);
138         visit(startI,startJ);
139     }
140     printf("-----------------------------------------\n");
141     printf("\n显示迷宫:\n\n");
142     print(maze);
143     printf("\n共有%d种方案\n",t);
144     min=a[0];
145     for(i=1;i<t;i++)
146     {
147         if(min>a[i])
148             min=a[i];
149     }
150     for(i=0;i<t;i++)
151     {
152         if(a[i]==min)
153             b[mini++]=i+1;
154     }
155     printf("最短需移动%d步。\n\n",min);
156     if(mini==1)
157         printf("最短路径仅有%d条为:\n",mini);
158     else
159         printf("最短路径有%d条,分别为:\n",mini);
160     for(i=0;i<mini;i++)
161     {
162         printf("路径%d\t",b[i]);
163         if((i+1)%5==0)
164             printf("\n");
165     }
166     printf("\n\n");
167     printf("是否要查看某一路径图案(1:是,0:否):");
168     scanf("%d",&isok);
169     printf("\n");
170     if(isok==0)
171         return 0;
172     while(flag)
173     {
174         printf("请输入您要显示的路径图案(其中0为迷宫图):");
175         scanf("%d",&lu);
176         if(lu>t)
177         {
178             printf("您所输入的数字超出了要查看的最大路径号%d,请重新输入\n\n",t);
179             continue;
180         }
181         printf("\n");
182         print_show(maze,li[lu].frist,li[lu].last);
183         printf("\n");
184         printf("是否继续查看(1:是,0:否):");
185         scanf("%d",&isok);
186         printf("\n");
187         if(isok==0)
188             flag=false;
189     }
190     return 0;
191 }
View Code

 

posted @ 2013-09-09 18:04  徐航  阅读(700)  评论(0编辑  收藏  举报