集训第三天(2017/8/2):继续刷搜索题

      今天还是刷搜索题,做dfs的题还是漏洞百出,除了练习关于dfs的题之外,还复习了广度优先搜索bfs,其实广度优先搜索的核心思想是:从初始节点开始,应用算符生成第一层节点,检查目标节点是否在这些后继结点中,若没有,再用产生式规则将所有第一层节点逐一扩展,得到第二层节点,并逐一检查第二层节点中是否包含目标节点,若没有,再用算符逐一扩展到第二层的所有节点......如此依次拓展检查下去,直至发现目标节点位置。广度优先算法一般用队列来实现。

      如果目标节点的深度与“费用”(如路径长度)成正比,那么找到第一个解即为最优解,这是,搜索速度比dfs更快,再求最优解时一般采用bfs。

     下面附上我今天练习的bfs例题:

eg1.最短路线(课本p303)

#include<iostream>
#include<cstring>
using namespace std;
int map[9][9]={{0,0,0,0,0,0,0,0,0},//将地图存储进去
               {0,1,0,0,0,1,0,1,1},
               {0,0,1,1,1,1,0,1,1},
               {0,0,1,1,0,0,1,1,1},
               {0,0,1,0,1,1,1,0,1},
               {0,1,1,0,1,1,1,0,0},
               {0,0,0,1,1,1,1,1,0},
               {0,1,1,1,0,0,1,1,0},
               {0,1,1,1,1,0,0,0,1}};//0表示能走,1表示不能走
int a[101],b[101];//a[k]表示经过k城市,b[k]记录k城市的前趋城市(前一个城市)
bool s[9];//s[i]用来判断第i个城市是否走过
int out(int d)
{if(b[d])out(b[d]);
  {
cout<<char(a[d]+64);
    while(b[d])
    {
        d=b[d];
        cout<<"--"<<char(a[d]+64);
    }
    cout<<endl;}
}
void bfs()
{
    int head,tail,i;//head表示到达第head层
    head=0;tail=1;
    a[1]=1;
    b[1]=0;
    s[1]=1;
    do{
    head++;//队首加一,出队
    for(i=1;i<=8;i++)//搜索可直通城市
    if((!map[a[head]][i])&&(s[i]==0))//判断该直通城市是否走过
    {
        tail++;//队尾加一,入队
        a[tail]=i;
        b[tail]=head;
        s[i]=1;
        if(i==8)
        {
           out(tail);
           head=tail;
           break;
        }
    }
    }while(head<tail);
}
int main()
{
    memset(s,0,sizeof(s));
    bfs();
    return 0;

eg2.迷宫问题(课本p308)

#include<iostream>
using namespace std;
int u[5]={0,0,1,0,-1};
int w[5]={0,1,0,-1,0};
int n,m,i,j,desx,desy,soux,souy,head,tail,x,y,a[51],b[51],pre[51],map[51][51];
bool f;
int print(int d)
{
    if(!pre[d]) print(pre[d]);
    cout<<a[d]<<","<<b[d]<<endl;
}
int main()
{
    int i,j;
    cin>>n>>m;
    for(i=0;i<=n;i++)
      for(j=1;j<=m;j++)
      cin>>map[i][j];
      cin>>soux>>souy;//入口
      cin>>desx>>desy;//出口
      head=0;
      tail=1;
      f=0;
      map[soux][souy]=-1;
      a[tail]=soux;b[tail]=souy;//入队
      pre[tail]=0;
      while(head!=tail)//队列不为空
      {
          head++;
          for(i=1;i<=4;i++)
          {
              x=a[head]+u[i];
              y=b[head]+w[i];
              if(x>0&&x<=n&&y>0&&y<=m&&map[x][y]==0)
              {
                  tail++;
                  a[tail]=x;
                  b[tail]=y;//入队
                  pre[tail]=head;
                  map[x][y]=-1;
                  if(x==desx&&y==desy)
                  {
                      f=1;
                      print(tail);
                      break;
                  }
              }
          }
          if(f) break;
      }
     if(!f) cout<<"no way."<<endl;
     return 0;
}

当然还有HDU上的作业题,就先不贴上了,以后再专门 写篇文章....

还有希望明天的练习赛不会输的那么惨...大哭

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值