深搜与广搜以及例题

做题目的时候,遇见了两个类型十分相似的题目,可以一个直接输出最短的步数,一个要保存,,这个就很犯难

然后通过这两题,有重新了解了一个BFS与DFS的区别

一、路径的输出

1.dfs

DFS其实就是一直顺着一个方向不断的搜索知道找到了目标为止。路径输出的时候,利用记录前面的点即可

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
#define N 9

int cnt;
struct Point{
    int x;
    int y;
}path[N*N];

int maze[N][N];  
int vis[N][N];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
Point star,end;

void output()
{
    printf("(%d,%d)->",star.x,star.y);
    for(int i=1;i<cnt-1;i++)
        printf("(%d,%d)->",path[i].x,path[i].y);
    printf("(%d , %d)\n\n" , end.x , end.y);
    printf("\n");
}

void DFS(int x,int y,int step)
{
    int tmp_x,tmp_y;
    Point p;
    if(x==end.x&&y==end.y)
    {
        cnt=step;
        output();
        return;
    }
    for(int i=0;i<4;i++)
    {
        temp_x=x+dir[i][0];
        temp_y=y+dir[i][1];
        p.x=tmp_x;
        p.y=tmp_y;
        if(!maze[tmp_x][tmp_y]&&!vis[tmp_x][tmp_y])
        {
            vis[x][y]=1;
            path[step]=p;//标记前面一个点
            DFS(tmp_x,tmp_y,step+1);
            vis[x][y]=0;
        }
    }
}
int main(){
   memset(vis , 0 , sizeof(vis));
   DFS(star.x , star.y , 1);
   return 0;
}
2 bfs

bfs就是不断向四周扩展,然后找到目标节点,利用数组模拟队列(或者直接利用STL的队列,可是STL里面的队列用于保存路径有些麻烦,适用于求最小步数)

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<map>
using namespace std;

#define MAXN 500010
#define N 10

int ans,end;
int sx,sy,ex,ey;
int vis[N][N];
int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
char mp[N][N];
struct Point{
    int x;
    int y;
    int pre;  //保存之前一个点的下标
    int d;  //保存来自哪一个方向
    int step;  //当前的步数
}p[MAXN];

void BFS()
{
    int front,rear;
    front=0,rear=1;
    memset(vis,0,sizeof vis);
    p[front].x=sx,p[front].y=sy;
    p[front].pre=0,p[front].step=0;
    vis[sx][sy]=1;

    while(front<rear)
    {
        Point tmp=p[front];
        if(tmp.x == ex && tmp.y == ey){/*如果找到了*/
          end = front;/*记下最后一个点的下标*/
          ans = tmp.step;  /*求出最短的步数*/
          break;
       }
       front++;
       for(int i=0;i<8;i++)
       {
           if(tmp.x+dir[i][0] <= 0 || tmp.x+dir[i][0] > 8)
            continue;
           if(tmp.y+dir[i][1] <= 0 || tmp.y+dir[i][1] > 8)
            continue;
           if(vis[tmp.x+dir[i][0]][tmp.y+dir[i][1]])
            continue;
           vis[tmp.x+dir[i][0]][tmp.y+dir[i][1]] = 1;/*标记为走过*/
           p[rear].x=tmp.x+dir[i][0],p[rear].y=tmp.y+dir[i][1];
           p[rear].pre=front-1;
           p[rear].d=i;
           p[rear++].step=tmp.step+1;
       }
    }
}
void output(int x)
{
    if(x==0)
        return;
    output(p[x].pre);
    printf("%s\n",mp[p[x].d]);
}
int main()
{
    scanf("%d%d%d%d" , &sx , &sy , &ex , &ey);/*输入起点和终点的坐标*/
    BFS();
    printf("%d\n" , ans);
    output(end);
    return 0;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值