BFS&&DFS学习

来源:互联网 发布:excel删除数据不重复项 编辑:程序博客网 时间:2024/06/05 12:40

Description

X,作为户外运动的忠实爱好者,总是不想呆在家里。现在,他想把死宅Y从家里拉出来。问从X的家到Y的家的最短时间是多少。

Input

多组输入。每组测试数据首先输入两个整数n,m(1<= n ,m<=15 )表示地图大小。接下来的n 行,每行n个字符。保证输入数据合法。

Output

若X可以到达Y的家,输出最少时间,否则输出 -1。

Sample Input

3 3X#Y***#*#3 3X#Y*#*#*#

Sample Output

4-1

//DFS
#include"iostream"#include"cstdio"#include "cstring"#include"cstdlib"using namespace std;struct note{int x,y,step;}que[300];char Map[16][16];int vis[16][16];int n,m;int Min;//定义一个最小的变量来求出X到Y的最短时间(因为由DFS搜索可能搜索出好几条路径)int jx[4]={0,0,1,-1},jy[4]={1,-1,0,0};void DFS(int x,int y,int step){  vis[x][y]=1;//此处把走过的点赋为1,下面在调用时就不用再赋值,如   if(step>=Min)return;//若步长已经大于最小值了,没必要判断此路径了,一定不是最短路径   if(Map[x][y]=='Y')   {       if(step<Min)       {          Min=step;//若有更短路径,用Min记住此路径所用时间       }       return;   }   note f;   for(int i=0;i<4;i++)   {    f.x=x+jx[i];f.y=y+jy[i];        if(f.x>=0&&f.x<n&&f.y>=0&&f.y<m&&Map[f.x][f.y]!='#'&&!vis[f.x][f.y])        {            DFS(f.x,f.y,step+1);//此处上一步不用再让走过点为1,因为在DFS开始时,已经有赋为1,如果调用会到那一步,因此不必再多余            vis[f.x][f.y]=0;//若递归时遇到return,此点并没有进行判断操作,即没有走,因此再重新设为0,即没走状态。返回到第一层进行下面的操做,即找其他点,        }   }}int main(){    while(~scanf("%d%d",&n,&m))    {memset(vis,0,sizeof(vis));        int i,j;            for( i=0;i<n;i++)            scanf("%*c%s",Map[i]);            for(i=0;i<n;i++)        {            for(j=0;j<m;j++)                if(Map[i][j]=='X')                break;            if(j<m)break;        }        Min=(1<<20);//将1按位左移20位赋给Min        DFS(i,j,0);//DFS搜索由于涉及递归调用,所以比BFS多一个参数        if(Min==(1<<20))//若Min没有改变,即DFS没有搜索到符合条件的,此时也就是X不能到Y家的情况            printf("-1\n");        else            printf("%d\n",Min);    }    return 0;}
//BFS
#include "iostream"#include"cstdio"#include"cstring"#include"cstdlib"using namespace std;struct node{int x,y,step;}que[300];//建立关于节点的架构,后面跟随一个记录点的数组char Map[16][16];//储存地图int vist[16][16];//储存访问的点int n,m;int jx[4]={0,0,1,-1},jy[4]={1,-1,0,0};//可以往四个方向移动,移动是对应在坐标中想x,y的数值变化void BFS(int x,int y)//BFS的代码{    node f,t;//架构f,t    f.x=x;f.y=y;f.step=0;//架构f赋值    vist[f.x][f.y]=1;//走过的点变成真,即为1    int ru=0,chu=0;//进队列和出队列的计数    que[ru++]=f;//第一个点,即X所在点进队    while(chu<ru)//保证队列中进队列个数大于等于出队列个数    {        t=que[chu++];//点出队列进行下面的判断        if(Map[t.x][t.y]=='Y')//如果找到‘Y’,返回        {            printf("%d\n",t.step);            return;        }        for(int i=0;i<4;i++)//在一个点没找到‘Y’,沿此点四个方向运动(c++中可以用时定义变量,注意此处int)        {            f.x=t.x+jx[i];//沿上下左右四个方向运动            f.y=t.y+jy[i];            if(f.x>=0&&f.x<n&&f.y>=0&&f.y<m&&Map[f.x][f.y]!='#'&&!vist[f.x][f.y])//移动到一点时,判断其是否可以进队列            {                vist[f.x][f.y]=1;//找出点存在que中,在出队列时,若此点走过,由上面if中!vist[f.x][f.y]可以不再存储走过的点                f.step=t.step+1;                que[ru++]=f;            }        }    }    printf("-1\n");    return;}int main(){while(~scanf("%d%d",&n,&m))//相当于while(scanf("%d%d",&n,&m)!=EOF){memset(vist,0,sizeof(vist));int i,j;    for( i=0;i<n;i++)//输入各值        scanf("%*c%s",Map[i]);    for( i=0;i<n;i++)//寻找X    {        for (j=0;j<m;j++)        if(Map[i][j]=='X')        break;      if(j<m)break;    }    BFS(i,j);//此处不是j-1,因为break后,就没有+1}return 0;}

0 0
原创粉丝点击