广度优先搜索BFS

广度优先搜索BFS

必须学习过队列、结构体(pair)才能够学广度优先搜索

B3625 迷宫寻路

可以让学生用深搜做一遍,复习一下深搜

然后讲广搜

 1 //深搜 60分 
 2 #include<iostream>
 3 #include<queue>
 4 using namespace std;
 5 int n,m,flag;
 6 char a[110][110];
 7 int dx[5]= {0,-1,0,1,0};
 8 int dy[5]= {0,0,1,0,-1};
 9 void dfs(int x,int y) {
10     if(flag) return;
11     if(x==n&&y==m) {
12         flag=1;
13         return;
14     }
15     for(int i=1; i<=4; i++) {
16         int nx=x+dx[i];
17         int ny=y+dy[i];
18         if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]=='.') {
19             a[nx][ny]='#';
20             dfs(nx,ny);
21             a[nx][ny]='.';
22         }
23     }
24     return;
25 }
26 int main() {
27     cin>>n>>m;
28     for(int i=1; i<=n; i++) {
29         for(int j=1; j<=m; j++) {
30             cin>>a[i][j];
31         }
32     }
33     dfs(1,1);
34     if(flag) cout<<"Yes"<<endl;
35     else cout<<"No"<<endl;
36     return 0;
37 }
 1 //广搜 100分
 2 #include<iostream>
 3 #include<queue>
 4 #include<utility>
 5 using namespace std;
 6 typedef pair<int,int> pii;
 7 pii a,b;
 8 int n,m,flag;
 9 char c[110][110];
10 int dx[5]= {0,-1,0,1,0};
11 int dy[5]= {0,0,1,0,-1};
12 void bfs(int x,int y) {
13     queue<pii> q;
14     a.first=x;
15     a.second=y;
16     q.push(a);
17     while(!q.empty()) {
18         a=q.front();
19         q.pop();
20         for(int i=1; i<=4; i++) {
21             int nx=a.first+dx[i];
22             int ny=a.second+dy[i];
23             if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&c[nx][ny]=='.') {
24                 b.first=nx;
25                 b.second=ny;
26                 if(nx==n&&ny==m) {
27                     flag=1;
28                     return;
29                 }
30                 q.push(b);
31                 c[nx][ny]='#';
32             }
33         }
34     }
35     return;
36 }
37 int main() {
38     cin>>n>>m;
39     for(int i=1; i<=n; i++) {
40         for(int j=1; j<=m; j++) {
41             cin>>c[i][j];
42         }
43     }
44     bfs(1,1);
45     if(flag) cout<<"Yes"<<endl;
46     else cout<<"No"<<endl;
47     return 0;
48 }

B3626 跳跃机器人

//B3626 跳跃机器人
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int n;
int vis[1000010];
queue<int> q;
void bfs() {
    memset(vis,-1,sizeof vis);
    q.push(1);
    vis[1]=0;
    while(!q.empty()) {
        int t=q.front();
        q.pop();
        if(t==n) {
            cout<<vis[n];
            return;
        }
        if(t-1>=1&&t-1<=n&&(vis[t-1]>vis[t]+1||vis[t-1]==-1)) {    //t-1
            q.push(t-1);
            vis[t-1]=vis[t]+1;
        }
        if(t+1>=1&&t+1<=n&&(vis[t+1]>vis[t]+1||vis[t+1]==-1)) {    //t+1
            q.push(t+1);
            vis[t+1]=vis[t]+1;
        }
        if(2*t>=1&&2*t<=n&&(vis[2*t]>vis[t]+1||vis[2*t]==-1)) {    //t-1
            q.push(2*t);
            vis[2*t]=vis[t]+1;
        }
    }
    return;
}

int main() {
    cin>>n;
    bfs();
    return 0;
}

 

P1443 马的遍历

#include<iostream>
#include<queue>
#include<utility>
using namespace std;
typedef pair<int,int> pii;
pii a,b;
int n,m,flag;
int c[410][410];
int dx[8]= {-1,-2,-2,-1,1,2,2,1};
int dy[8]= {2,1,-1,-2,2,1,-1,-2}; //8个方向
void bfs(int x,int y) {
    queue<pii> q;
    a.first=x;
    a.second=y;
    q.push(a);
    while(!q.empty()) {
        a=q.front();
        q.pop();
        for(int i=0; i<8; i++) {
            int nx=a.first+dx[i];
            int ny=a.second+dy[i];
            if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&c[nx][ny]==-1) {
                b.first=nx;
                b.second=ny;
                q.push(b);
                c[nx][ny]=c[a.first][a.second]+1;
            }
        }
    }
    return;
}
int main() {
    int x,y;
    cin>>n>>m>>x>>y;
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            c[i][j]=-1;
        }
    }
    c[x][y]=0;
    bfs(x,y);
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            printf("%5d",c[i][j]);
        }
        cout<<endl;
    }
    return 0;
}

 P2802 回家

//P2802 回家
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=15;
int n,m,sx,sy,f=1;
int g[N][N];
int vis[N][N];//记录血量
int dx[]= {0,0,-1,1};
int dy[]= {-1,1,0,0};
struct nodes {
    int x,y,ti;
} t;
void bfs() {
    memset(vis,-1,sizeof vis);
    queue<nodes> q;
    q.push({sx,sy,0});
    vis[sx][sy]=6;
    while(!q.empty()) {
        t=q.front();
        q.pop();
        if(g[t.x][t.y]==3&&vis[t.x][t.y]!=0) { //到家了
            cout<<t.ti;
            f=0;
            return;
        }
        if(g[t.x][t.y]==4) vis[t.x][t.y]=6;//补血
        if(vis[t.x][t.y]>1) {//血量必须大于1才能继续往下走
            for(int i=0; i<4; i++) {
                int xx=t.x+dx[i];
                int yy=t.y+dy[i];
                if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&g[xx][yy]!=0&&vis[t.x][t.y]-1>=vis[xx][yy]) {
                    vis[xx][yy]=vis[t.x][t.y]-1;
                    q.push({xx,yy,t.ti+1});
                }
            }
        }
    }
}

int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            cin>>g[i][j];
            if(g[i][j]==2) {
                sx=i;
                sy=j;
            }
        }
    }
    bfs();
    if(f) cout<<-1;
    return 0;
}

P3958 [NOIP2017 提高组] 奶酪

//P3958 [NOIP2017 提高组] 奶酪
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
long long T,n,h,r;
long long x[1010],y[1010],z[1010],vis[1010];
struct nodes {
    long long x,y,z;
} t;
queue<nodes> q;

bool dis(int i,nodes u) {
    long long xx=x[i]-u.x;
    long long yy=y[i]-u.y;
    long long zz=z[i]-u.z;
    return xx*xx+yy*yy+zz*zz<=4*r*r;
}

int main() {
    scanf("%lld",&T);
    while(T--) {
        memset(vis,0,sizeof vis);
        scanf("%lld %lld %lld",&n,&h,&r);
        for(int i=1; i<=n; i++) {
            scanf("%lld %lld %lld",&x[i],&y[i],&z[i]);
            if(z[i]-r<=0) { //入口
                q.push({x[i],y[i],z[i]});
                vis[i]=1;
            }
        }
        int f=1;
        while(!q.empty()) {
            t=q.front();
            q.pop();
            if(t.z+r>=h) {
                printf("Yes\n");
                f=0;
                break;
            }
            for(int i=1; i<=n; i++) {
                if(!vis[i]&&dis(i,t)) {
                    q.push({x[i],y[i],z[i]});
                    vis[i]=1;
                }
            }
        }
        if(f) printf("No\n");
        while(!q.empty())  q.pop();
    }
    return 0;
}

 

P3956 [NOIP2017 普及组] 棋盘

//P3956 [NOIP2017 普及组] 棋盘
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=1010;
int n,m,x,y,c,ans=N*N*2;
int g[N][N],vis[N][N];
int dx[]= {0,0,1,-1},dy[]= {1,-1,0,0};
struct nodes {
    int x,y;
    int color,cost;//-1表示没有变色,1红色,2黄色
} t;
void bfs() {
    memset(vis,0x3f,sizeof vis);
    queue<nodes> q;
    q.push({1,1,-1,0});
    vis[1][1]=0;
    while(!q.empty()) {
        t=q.front();
        q.pop();
        if(t.x==m&&t.y==m) {//出口
            ans=min(ans,t.cost);
            continue;
        }
        if(t.cost>=ans) continue;//剪枝
        for(int i=0; i<4; i++) {
            int xx=t.x+dx[i];
            int yy=t.y+dy[i];
            if(xx>=1&&xx<=m&&yy>=1&&yy<=m) {//在地图范围内
                if(t.color==-1) { //原本格子有颜色
                    if(g[xx][yy]==g[t.x][t.y]&&vis[xx][yy]>t.cost) { //下一个格子颜色相同
                        vis[xx][yy]=t.cost;
                        q.push({xx,yy,-1,t.cost}) ;
                    } else if(g[xx][yy]!=0&&g[xx][yy]!=g[t.x][t.y]&&vis[xx][yy]>1+t.cost) {//下一个格子颜色不相同
                        vis[xx][yy]=t.cost+1;
                        q.push({xx,yy,-1,t.cost+1}) ;
                    } else if(g[xx][yy]==0&&vis[xx][yy]>=2+t.cost) { //填涂颜色
                        vis[xx][yy]=2+t.cost;
                        q.push({xx,yy,g[t.x][t.y],t.cost+2}) ;
                    }
                } else {//原本格子没有颜色,只能去有颜色的格子
                    if(g[xx][yy]!=0&&t.color==g[xx][yy]&&vis[xx][yy]>t.cost) {
                        vis[xx][yy]=t.cost;
                        q.push({xx,yy,-1,t.cost}) ;
                    }
                    else if(g[xx][yy]!=0&&t.color!=g[xx][yy]&&vis[xx][yy]>1+t.cost) {
                        vis[xx][yy]=1+t.cost;
                        q.push({xx,yy,-1,t.cost+1}) ;
                    }

                }
            }
        }
    }
    return;
}

int main() {
    scanf("%d %d",&m,&n);
    for(int i=1; i<=n; i++) {
        scanf("%d %d %d",&x,&y,&c);
        g[x][y]=c+1;//1 红色,2 黄色, 0 无色
    }
    bfs();
    if(ans==N*N*2) {
        cout<<-1;
    } else cout<<ans;
    return 0;
}

 

posted @ 2023-07-04 16:41  关于42号星球  阅读(165)  评论(0编辑  收藏  举报