C的迷宫问题

C的迷宫问题,第1张

1回溯算法

7. 迷宫问题

给一个20×20的迷宫、起点坐标和终点坐标,问从起点是否能到达终点。

输入数据:’’表示空格;’X’表示墙。

程序如下:

#include <stdioh>

#include <mathh>

void search(int,int);

int canplace(int,int);

void readdata(); //读入数据

void printresult(); //打印结果

int a[20][20]; //a数组存放迷宫

int s,t;

int main()

{

int row, col;

readdata();

row=s/20;

col=s%20;

search(row,col); //递归搜索

printresult();

}

void search(int row, int col)

{

int r,c;

a[row][col]=1;

r=row; //左

c=col-1;

if(canplace(r,c)) //判断(r,c)位置是否已经走过

search(r,c); //递归搜索(r,c)

r=row+1; //下

c=col;

if(canplace(r,c)) //判断(r,c)位置是否已经走过

search(r,c); //递归搜索(r,c)

r=row; //右

c=col+1;

if(canplace(r,c)) //判断(r,c)位置是否已经走过

search(r,c); //递归搜索(r,c)

r=row-1; //上

c=col;

if(canplace(r,c)) //判断(r,c)位置是否已经走过

search(r,c); //递归搜索(r,c)

}

void printresult()

{

int i,j;

for(i=0;i<20;i++)

{

for(j=0;j<20;j++)

printf("%3d",a[i][j]);

printf("\n");

}

}

void readdata()

{

int i,j;

for(i=0;i<20;i++)

{

for(j=0;j<20;j++)

scanf("%d",&a[i][j]);

}

}

int canplace(int row, int col)

{

if(row>=0&&row<20&&col>=0&&col<20&&a[row][col]==0)

return 1;

else

return 0;

}

2搜索算法

如下图12×12方格图,找出一条自入口(2,9)到出口(11,8)的最短路径。

抱歉,图案粘贴不上

本题给出完整的程序和一组测试数据。状态:老鼠所在的行、列。程序如下:

#include<stdioh>

void readdata(); //读入数据

void init(); //初始化

int search(); //广搜,并在每一个可到达的每一个空格出填上最小步数

int emptyopen(); //判栈是否为空:空:1;非空:0。

int takeoutofopen(); //从栈中取出一个元素,并把该元素从栈中删除

int canmoveto(int,int,int,int,int); //判能否移动到该方向,并带回坐标(r,c)

int isaim(int row, int col); //判断该点是否是目标

int used(int,int); //判断该点是否已经走过

void addtoopen(int,int); //把该点加入到open表

int a[12][12]; //a存放迷宫,0表示空格,-2表示墙。

//广搜时,未找到目标以前到达的空格,填上到达该点的最小步数

int n; //n为迷宫边长,注:若大于12,必须修改一些参数,如a的大小

int open[20],head,tail,openlen=20; //open表

int s,t; //起点和终点

int main()

{

int number;

readdata(); //读取数据

init(); //初始化

number=search(); //广搜并返回最小步数

printf("%d",number); //打印结果

}

int search()

{

int u, row, col, r, c, i, num;

while(!emptyopen()) //当栈非空

{

u=takeoutofopen(); //从栈中取出一个元素,并把该元素从栈中删除

row=u/n; //计算该点的坐标

col=u%n;

num=a[row][col]; //取得该点的步数

for(i=0;i<4;i++)

{

if(canmoveto(row,col,&r,&c,i)) //判能否移动到该方向,并带回坐标(r,c)

{

if(isaim(r,c)) //如果是目标结点

return(num+1); //返回最小步数

if(!used(r,c)) //如果(r,c)还未到达过

{

a[r][c]=num+1; //记录该点的最小步数

addtoopen(r,c); //把该点加入到open表

}

}

}

}

}

int emptyopen()

{

if(head==tail)

return(1);

else

return(0);

}

int takeoutofopen()

{

int u;

if(head==tail)

{

printf("errer: stack is empty");

return(-1);

}

u=open[head++];

head=head%openlen;

return(u);

}

int canmoveto(int row, int col, int p, int q, int direction)

{

int r,c;

r=row;

c=col;

switch(direction)

{

case 0: c--; //左

break;

case 1: r++; //下

break;

case 2: c++; //右

break;

case 3: r--; //上

}

p=r;

q=c;

if(r<0||r>=n||c<0||c>=n) //如果越界返回0

return(0);

if(a[r][c]==0) //如果是空格返回1

return(1);

return(0); //其余情况返回0

}

int isaim(int row, int col)

{

if(rown+col==t)

return(1);

else

return(0);

}

int used(int row, int col)

{

if(a[row][col]==0) // 0表示空格

return(0);

else

return(1);

}

void addtoopen(int row, int col)

{

int u;

u=rown+col;

open[tail++]= u;

tail=tail%openlen;

}

void readdata()

{

int i,j,row,col;

char str[20];

scanf("%d",&n);

scanf("%d%d",&row,&col); //起点坐标

s=rown+col;

scanf("%d%d",&row,&col); //终点坐标

t=rown+col;

gets(str);

for(i=0;i<n;i++)

{

gets(str);

for(j=0;j<n;j++)

if(str[j]=='')

a[i][j]=0; //0表示空格

else

a[i][j]=-2; //-2表示墙

}

}

void init()

{

head=0;

tail=1;

open[0]=s;

}

测试数据如下:

12 10 7 1 8

XXXXXXXXXXXX

XXXXX

XXXXX

XXXXXXXX

XXXX

XXXXXXXXXXX

XXXX

XXXXXXXX

XXX

XXXXXXXXX

XXXXXXXXXX

XXXXXXXXXXXX

#include <stdioh> #include <memh> void main() { int a[100][100]; //0:blocked 1:passage 2:finish -1:visited; int b[10000][2]; int m=0,n=0; int sttop=0; int i,j,k,l; memset(a,0,sizeof(a)); printf("Please Input m,n:"); scanf("%d%d",&m,&n); printf("Input the start:"); scanf("%d%d",&i,&j); b[0][0]=i-1; b[0][1]=j-1; printf("Input the Map:\n"); for (i=0;i<m;i++) for (j=0;j<n;j++) { scanf("%d",&a[i][j]); } printf("Input the Finish:"); scanf("%d%d",&i,&j); a[i-1][j-1]=2; i=b[sttop][0];j=b[sttop][1]; a[i][j]=-1; while (sttop!=-1) { if (i>0) { //can up if (a[i-1][j]==1) { a[--i][j]=-1; b[++sttop][0]=i; b[sttop][1]=j; continue; }else if (a[i-1][j]==2) { b[++sttop][0]=--i; b[sttop][1]=j; break; } } if (i<m-1) { //can up if (a[i+1][j]==1) { a[++i][j]=-1; b[++sttop][0]=i; b[sttop][1]=j; continue; }else if (a[i+1][j]==2) { b[++sttop][0]=++i; b[sttop][1]=j; break; } } if (j>0) { //can left if (a[i][j-1]==1) { a[i][--j]=-1; b[++sttop][0]=i; b[sttop][1]=j; continue; }else if (a[i][j-1]==2) { b[++sttop][0]=i; b[sttop][1]=--j; break; } } if (j<m-1) { //can up if (a[i][j+1]==1) { a[i][++j]=-1; b[++sttop][0]=i; b[sttop][1]=j; continue; }else if (a[i][j+1]==2) { b[++sttop][0]=i; b[sttop][1]=j++; break; } } sttop--; } if (sttop+1) { for (i=0;i<sttop;i++) printf("(%d,%d)->",b[i][0]+1,b[i][1]+1); printf("(%d,%d)\n",b[i][0]+1,b[i][1]+1); } else printf("Can't Reach The Finish Spot!\n"); return; } 用非嵌套的方法做的栈,起点 终点自己定 输入数据规则如下: 先输入m n(m为行数,n为列数) 再输入起点(最左上角为(1,1)(前者行号,后者列号)则输入"1 1"(不含引号)其他依次类推) 再输入地图(0为被阻挡,1为通路)(起点被默认为通路,无论输入0还是1) 再输入终点(规则和起点一样) 回车后出结果,结果的表达方式以(x,y)->(x,y)->->(x,y)(坐标任以1,1为左上角) 或者Can't Reach The Finish Spot! 呈现 其他的修改的话可以随便咯(规模m,n<=100,太大栈放不下了)

遍历的时候没有把已经尝试过的地方做标记

int explore(int i,int j,int i0,int j0)

{

int k=0,i1=0,j1=0;

int changes[4][2]=

{

{-1,0},

{1,0},

{0,-1},

{0,1}

};

if(i==n&&j==m)

{

return 1;

}

else

{

matrix[i][j] = -1;

for(k=0;k<=3;k++)

{

int ti = i+changes[k][0];

int tj = j+changes[k][1];

if(matrix[ti][tj] == -1)

continue;

i1=ti;

j1=tj;

if((i1!=i||j1!=j)&&(isValidChoice(i1,j1)==1))

{

if(explore(i1,j1,i,j)==1)

{

return 1;

}

}

}

return 0;

}

}

以上就是关于C的迷宫问题全部的内容,包括:C的迷宫问题、C语言迷宫问题,用栈来做、c语言挑错 迷宫问题 下附代码 在线等等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10215666.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存