BFS 入门

由于深搜过于复杂(。。我蒟蒻),于是从广搜写起。。
话不多说,上代码
hdu 1312
踩地板问题,用广搜从题中定义方向开始搜索,逐一标记即可。
bfs入门题

#include <bits/stdc++.h>
using namespace std;
char room[30][30];
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};//每次搜索查找的范围。
int wx,wy,num;
#define CHECK(x,y)(x<wx&&x>=0&&y<wy&&y>=0)//比定义一个函数调用起来更快。
struct node{int x,y;};//定义结构体来存坐标。
void bfs(int dx,int dy){
num=1;
queue<node>q;//用对列来记录可以搜索的位置。
node start,next;//用两个名字分别记录位置。
start.x=dx;//记录起始位置。
start.y=dy;
q.push(start);//先将起始位置存入队列里面。
while(!q.empty()){//逐一检验队列储存位置是否能拓展。
        start=q.front();
        q.pop();//将将要检验的位置出队列。
        for(int i=0;i<4;i++){
            next.x=start.x+dir[i][0];//记录下一步的位置。
            next.y=start.y+dir[i][1];
            if(CHECK(next.x,next.y)&&room[next.x][next.y]=='.'){
                num++;
                room[next.x][next.y]='#';//将’走‘过的路做标记。
                q.push(next);//进队列。

             }
          }
        }
    }
int main()
{
    int x,y,dx,dy;
    while(cin>>wx>>wy){
        if(wx==0&&wy==0)break;
        for(int i=0;i<wy;i++){
            for(int j=0;j<wx;j++){
                    cin>>room[j][i];
            if(room[j][i]=='@'){
                dx=j;dy=i;//记录起始位置。
            }
            }
        }
        num=0;
        bfs(dx,dy);
        cout<<num<<endl;
    }
    return 0;
}

再来一道入门题
洛谷 1443 马的遍历
更上一道题思路一样,逐一标记判断,区别在于计数方式不同。

#include <bits/stdc++.h>

#define CHECK(y,x) (x>=1&&x<=wx&&y>=1&&y<=wy)//迷。。
using namespace std;
int map1[405][405];//定义一个棋盘。
int wx,wy;//wx是棋盘的列数,wy是棋盘的行数。
struct node{int x,y;};//用结构体来记录每次广搜的坐标。
int dir[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};//标记马行走方位。
void bfs(int x,int y){
node start,next;//用两个结构体变量来记录位置。
memset(map1,-1,sizeof(map1));//标记未到达位置。
start.x=x;start.y=y;
queue<node>q;
q.push(start);
map1[start.x][start.y]=0;//记录步骤。
while(!q.empty()){
    start=q.front();
    q.pop();
    for(int i=0;i<8;i++){
    next.x=start.x+dir[i][0];
    next.y=start.y+dir[i][1];
    if(CHECK(next.x,next.y)&&map1[next.x][next.y]==-1){
        map1[next.x][next.y]=map1[start.x][start.y]+1;//记录所用步骤。
        q.push(next);//存放新坐标。
    }}


}
}
int main()
{  int  x,y;
    while(cin>>wy>>wx>>x>>y){//wy是行数,wx是列数。
        bfs(x,y);
        for(int i=1;i<=wy;i++)
            for(int j=1;j<=wx;j++)
        j!=wx?printf("%-5d",map1[i][j]):printf("%-5d\n",map1[i][j]);}

    return 0;
}

再来一道类似的(愉快水题)
洛谷 1596 USACO
bfs+标记

#include <bits/stdc++.h>
#define CHECK(y,x) (x<dx&&x>=0&&y>=0&&y<dy)
using namespace std;
struct node{int x,y;};
int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1}};
char map1[101][101];
int dx,dy,num=0;
void bfs(int y,int x)
{
  queue<node>q;
  node start,next;
  start.x=x;start.y=y;
  q.push(start);
  while(!q.empty()){
    start=q.front();
    q.pop();
    for(int i=0;i<8;i++)
    {
        next.x=start.x+dir[i][0];
        next.y=start.y+dir[i][1];
        if(CHECK(next.y,next.x)&&map1[next.y][next.x]=='W')
        {
            q.push(next);
            map1[next.y][next.x]='.';
        }
    }
  }
}
int main()
{
    ios::sync_with_stdio(0);
    cin>>dy>>dx;
    int x,y;
    for(int i=0;i<dy;i++)
        for(int j=0;j<dx;j++)
        cin>>map1[i][j];
    for(int i=0;i<dy;i++)
        for(int j=0;j<dx;j++)
    if(map1[i][j]=='W'){
        bfs(i,j);
        num++;}
        cout<<num<<endl;
        return 0;
}

搜索
也是入门题。

#include <bits/stdc++.h>

using namespace std;
#define CHECK(y,x) (x>=0&&x<4&&y>=0&&y<4)
char a[5][5];
int falg;
struct node{int x,y;};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

void bfs(int y,int x){
queue<node>q;
falg=0;
node start,next;
start.x=x;start.y=y;
q.push(start);
while(!q.empty()){
    start=q.front();
    q.pop();
    for(int i=0;i<4;i++){
        next.y=start.y+dir[i][0];
        next.x=start.x+dir[i][1];
        if(CHECK(next.y,next.x)&&a[next.y][next.x]=='#'){
            q.push(next);
            a[next.y][next.x]='*';}
            if(next.x==3&&next.y==3){
                falg=1;
                break;
            }
        }
    }
}
int main()
{
  int n;
  scanf("%d",&n);
  while(n--){
    for(int i=0;i<4;i++)
        scanf("%s",a[i]);
    bfs(0,0);
    if(falg)printf("YES\n");
    else printf("NO\n");

  }
    return 0;
}

最大黑色区域

#include <bits/stdc++.h>
#define CHECK(y,x) (y>=0&&y<dy&&x>=0&&x<dx)

using namespace std;

struct node{int x,y;};
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int dx,dy,num,ans=0;
int a[101][101];
int bfs(int y,int x)
{ queue<node>q;
    num=1;a[y][x]=0;
 node start,next;
 start.x=x;start.y=y;
 q.push(start);
 while(!q.empty()){
    start=q.front();
    q.pop();
    for(int i=0;i<4;i++){
        next.y=start.y+dir[i][0];
        next.x=start.x+dir[i][1];
        if(CHECK(next.y,next.x)&&a[next.y][next.x]==1){
            q.push(next);
            a[next.y][next.x]=0;
            num++;
        }
    }
 }
 return num;
}

int main()
{       int n;
    scanf("%d %d",&dy,&dx);
    for(int i=0;i<dy;i++)
        for(int j=0;j<dx;j++)
        scanf("%d",&a[i][j]);
    for(int i=0;i<dy;i++)
        for(int j=0;j<dx;j++)
      if(a[i][j]==1){
        n=bfs(i,j);
        if(ans<n)ans=n;}
        printf("%d\n",ans);
    return 0;
}

瓷砖-搜索

#include <bits/stdc++.h>
#define CHECK(y,x) (y>=0&&y<dy&&x>=0&&x<dx)

using namespace std;

struct node{int x,y;};
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int dx,dy,num;
char a[51][51];
void bfs(int y,int x)
{ queue<node>q;
    num=1;
 node start,next;
 start.x=x;start.y=y;
 q.push(start);
 while(!q.empty()){
    start=q.front();
    q.pop();
    for(int i=0;i<4;i++){
        next.y=start.y+dir[i][0];
        next.x=start.x+dir[i][1];
        if(CHECK(next.y,next.x)&&a[next.y][next.x]=='.'){
            q.push(next);
            a[next.y][next.x]='#';
            num++;
        }
    }
 }

}
int main()
{  scanf("%d %d",&dx,&dy);
    for(int i=0;i<dy;i++)
        scanf("%s",a[i]);
    for(int i=0;i<dy;i++)
        for(int j=0;j<dx;j++)
      if(a[i][j]=='@'){
        bfs(i,j);
        break;}
        printf("%d\n",num);
    return 0;
}

再写一道关于用map来优化搜索的题。。其实觉得加用string里的find()函数再标记后还能再优化。。等大佬指点
洛谷 1032

#include <bits/stdc++.h>

using namespace std;

map<string,int>m;
int ans,n,k;
string a,b;
string f[15],s[15];
struct node{string str;int step;};
string check(string str,int i,int j){//用来替换字符串和判断是否能进行替换。
string a="";
if(i+f[j].length()>str.length())return a;
for(k=0;k<f[j].length();k++)
    if(str[i+k]!=f[j][k])return a;
a=str.substr(0,i);//替换字符串。
a+=s[j];
a+=str.substr(i+k);
return a;}
void  bfs()
{ queue<node>q;
  node start,next;
  start.str=a;start.step=0;
  q.push(start);
  while(!q.empty()){
    start=q.front();
    q.pop();
    string temp;
    if(m[start.str]==1)continue;
    if(start.str==b){ans=start.step; break;}
    m[start.str]=1;
    for(int i=0;i<start.str.length();i++)//把每一位当做可以替换的首位来判断是否能替换。
    for(int j=0;j<n;j++){//将每组逐一判断。
        temp=check(start.str,i,j);
        if(temp!=""){
            next.str=temp;
            next.step=start.step+1;
            q.push(next);
        }
     }
  }
    if(ans>10||ans==0)printf("NO ANSWER!\n");
    else printf("%d\n",ans);

}
int main()
{
    cin>>a>>b;
    while(cin>>f[n]>>s[n])
        n++;
    bfs();
    return 0;
}

我又来写bfs了更新一道标记题
洛谷 1135 奇怪的电梯
细节有点多,优化的方式也很多。。不标记会MLE

#include <bits/stdc++.h>
#define check(n) (n>=1&&n<=h)
using namespace std;
int a[205],ans=12345,h,p,f;
struct node{int n,step;};
void bfs(){
    queue<node>q;
    node start,next;
    start.n=f;start.step=0;
    q.push(start);
    while(!q.empty()){
        start=q.front();
        q.pop();
        next.n=start.n+a[start.n];
        if(check(next.n)){
            next.step=start.step+1;
            q.push(next);
            if(next.n==p)
                ans=min(ans,next.step);
        }
        next.n=start.n-a[start.n];
        if(check(next.n)){
            next.step=start.step+1;
            q.push(next);
            if(next.n==p)
                ans=min(ans,next.step);
        }
        a[start.n]=12345;
    }
    }

int main()
{
  scanf("%d %d %d",&h,&f,&p);
  for(int i=1;i<=h;i++)
    scanf("%d",&a[i]);
    if(f==p)printf("0");
    else{
    bfs();
    if(ans==12345)printf("-1");
    else
    printf("%d",ans);}
    return 0;
}

(持续更新中。。)

猜你喜欢

转载自blog.csdn.net/weixin_46127031/article/details/105077506
BFS