层层递进----广度优先搜索

不恋尘世浮华,不写红尘纷扰,不叹世道苍凉,不惹情思哀怨,闲看花开,静待花落,冷暖自知,干净如始。

从谁开始就把谁存到队列里,从它开始进行以后的步骤,广搜的话会遇到许多分支一类的东西,每遇到一个分支就要push进队列里,每次处理判断时都要处理最前边的,即front(),处理的同时也要将其删掉pop(),方便可以一直处理front()的那个。在处理的过程中也要判断找寻是否是结果,进行判断。。。。进行广搜要灵活将struct与queue结合使用,化繁为简。
广搜适用于最短最小问题,先搜到的路径一定是最小的。

特点:

(1)在产生新的子结点时,深度越小的结点越先得到扩展,即先产生它的子结点。为使算法便于实现,存放结点的数据库一般用队列的结构。

(2)无论问题性质如何不同,利用广度优先搜索法解题的基本算法是相同的,但数据库中每一结点内容,产生式规则,根据不同的问题,有不同的内容和结构,就是同一问题也可以有不同的表示方法。

(3)当结点到跟结点的费用(有的书称为耗散值)和结点的深度成正比时,特别是当每一结点到根结点的费用等于深度时,用广度优先法得到的解是最优解,但如果不成正比,则得到的解不一定是最优解。这一类问题要求出最优解,一种方法是使用后面要介绍的其他方法求解,另外一种方法是改进前面深度(或广度)优先搜索算法:找到一个目标后,不是立即退出,而是记录下目标结点的路径和费用,如果有多个目标结点,就加以比较,留下较优的结点。把所有可能的路径都搜索完后,才输出记录的最优路径。(4)广度优先搜索算法,一般需要存储产生的所有结点,占的存储空间要比深度优先大得多,因此程序设计中,必须考虑溢出和节省内存空间得问题。

(5)广度优先搜索法一般无回溯操作,即入栈和出栈的操作,所以运行速度比深度优先搜索算法法要快些。

(其实吧,我觉得它最大的特点就是代码冗长,但是该会的还是得会,就这一块我迷了好一阵,还是先把模板给背了呢)

下面就贴几个例题吧,首先是用深搜做的那个迷宫问题。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
using namespace std;
int a[100][100],book[100][100];
int fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node
{
    int x;
    int y;
    int f;//这是用来输出路径的,此题没要求可以不写
    int s;
};
int main()
{
    struct node q[2501];
    int head,tail;
    int i,j,k,n,m,csx,csy,zdx,zdy,tx,ty,flag;
    cin>>n>>m;
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        cin>>a[i][j];
    cin>>csx>>csy>>zdx>>zdy;
    head=1;
    tail=1;
    q[tail].x=csx;
    q[tail].y=csy;
    q[tail].f=0;
    q[tail].s=0;
    tail++;
    book[csx][csy]=1;
    flag=0;
    while(head<tail)
    {
        for(k=0;k<4;k++)
        {
            tx=q[head].x+fx[k][0];
            ty=q[head].y+fx[k][1];
            if(tx>n||ty>m||tx<=0||ty<=0)
                continue;
            if(a[tx][ty]==0&&book[tx][ty]==0)
            {
                book[tx][ty]=1;
                q[tail].x=tx;
                q[tail].y=ty;
                q[tail].f=head;
                q[tail].s=q[head].s+1;
                tail++;
            }
            if(tx==zdx&&ty==zdy)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)
            break;
        head++;
    }
    cout<<q[tail-1].s;
    return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
using namespace std;
char a[25][25];
int fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node
{
    int x;
    int y;
};
int getnum(int i,int j)
{
    int sum,x,y;
    sum=0;//7用来计数
    x=i;
    y=j;
    while(a[x][y]!='#')
    {
        if(a[x][y]=='G')
            sum++;
        x--;
    }
    x=i;
    y=j;
    while(a[x][y]!='#')
    {
        if(a[x][y]=='G')
            sum++;
        x++;
    }
    x=i;
    y=j;
    while(a[x][y]!='#')
    {
        if(a[x][y]=='G')
            sum++;
        y--;
    }
    x=i;
    y=j;
    while(a[x][y]!='#')
    {
        if(a[x][y]=='G')
            sum++;
        y++;
    }
    return sum;
}
int main()
{
    struct node q[401];
    int head,tail;
    int book[20][20]={0};
    int i,j,k,n,m,mx,my,csx,csy,sum,ma=0,tx,ty;
    cin>>n>>m>>csx>>csy;
    for(i=0;i<n;i++)
        scanf("%s",a[i]);
    head=1;
    tail=1;
    q[tail].x=csx;
    q[tail].y=csy;
    tail++;
    book[csx][csy]=1;
    ma=getnum(csx,csy);
    mx=csx;
    my=csy;
    while(head<tail)
    {
        for(k=0;k<4;k++)
        {
         tx=q[head].x+fx[k][0];
            ty=q[head].y+fx[k][1];
            if(tx>n||ty>m||tx<=0||ty<=0)
                continue;
            if(a[tx][ty]=='.'&&book[tx][ty]==0)
            {
                book[tx][ty]=1;
                q[tail].x=tx;
                q[tail].y=ty;
                tail++;
                sum=getnum(tx,ty);
                if(sum>ma)
                {
                    ma=sum;
                    mx=tx;
                    my=ty;
                }
        }
    }
    head++;
    }
    printf("将炸弹放到(%d,%d)处,可以消灭%d个敌人\n",mx,my,ma);
    return 0;
}
/*13 13 3 3
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.#.#
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
运行结果:
将炸弹放到(7,11)处,可以消灭10个敌人*/

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值