• 红与黑(bfs + dfs 解法)(算法图论基础入门)


    红与黑问题

    前言

    献给阿尔吉侬的花束( 入门级bfs查找 + 模版解读 + 错误示范
    在之前的博客当中,详细地介绍了这类题目的解法,今天为大家带来一道类似的题目练练手,后续还会更新更有挑战的题目以及更为详细的解析,喜欢的小伙伴可以点个关注啦!

    问题描述

    有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。

    你站在其中一块黑色的瓷砖上,只能向相邻(上下左右四个方向)的黑色瓷砖移动。

    请写一个程序,计算你总共能够到达多少块黑色的瓷砖。

    输入格式
    输入包括多个数据集合

    每个数据集合的第一行是两个整数 W 和 H,分别表示 x 方向和 y 方向瓷砖的数量。

    在接下来的 H 行中,每行包括 W 个字符。每个字符表示一块瓷砖的颜色,规则如下

    1)‘.’:黑色的瓷砖;
    2)‘#’:红色的瓷砖;
    3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。

    当在一行中读入的是两个零时,表示输入结束。

    输出格式
    对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。

    数据范围
    1≤W,H≤20
    输入样例:

    6 9 
    ....#. 
    .....# 
    ...... 
    ...... 
    ...... 
    ...... 
    ...... 
    #@...# 
    .#..#. 
    0 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输出样例:

    45
    
    • 1

    bfs 解法

    话不多说,直接上代码,解析都在注释当中:

    #include
    #include
    #include
    using namespace std;
    const int N = 23;
    char g[N][N];
    int h,w,ans;
    typedef pair<int,int> PII;
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    void bfs(int x,int y){
        g[x][y]='#';
        queue<PII> q;
        q.push({x,y});//队列的初始化
        while(!q.empty()){
            auto t=q.front();
            q.pop();
            for(int i=0;i<4;i++){
                int a=t.first+dx[i];
                int b=t.second+dy[i];
                if(a>=1 && a<=h && b>=1 && b<=w && g[a][b]=='.'){
                    q.push({a,b});
                    ans++;
                    g[a][b]='#';//把走过的路封死
                    //防止重读走的现象
                }
            }
        }
    }
    int main(){
        while(cin>>w>>h,w||h){//注意这里的输入
        //宽和高要反着来
            int x,y;
            ans=0;
            for(int i=1;i<=h;i++){
                for(int j=1;j<=w;j++){
                    cin>>g[i][j];
                    if(g[i][j]=='@'){
                        x=i,y=j;//找到其实方块
                    }
                }
            }
            bfs(x,y);
            cout<<ans+1<<endl;
            //为什么要 +1 呢?
            //因为后续的bfs算法没有考虑最开始的那个方块
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    dfs 解法

    #include
    using namespace std;
    const int N =23;
    char g[N][N];
    int ans,h,w;
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    void dfs(int x,int y){
        g[x][y]='#';
        for(int i=0;i<4;i++){
            int a=x+dx[i];
            int b=y+dy[i];
            if(x>=1 && x<= h && y>=1 && y<=w && g[a][b]=='.'){
                dfs(a,b);
                ans++;
            }
        }
    }
    int main(){
        while(cin>>w>>h,w||h){
            ans=0;
            int x,y;
            for(int i=1;i<=h;i++){
                for(int j=1;j<=w;j++){
                    cin>>g[i][j];
                    if(g[i][j]=='@'){
                        x=i,y=j;
                    }
                }
            }
            dfs(x,y);
            cout<<ans+1<<endl;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    怎么用conda下载清华源的pytorch(自带cuda的版本)
    31、Java——JDBC实现账号密码登录
    Flutter教程之Dart 和 Flutter 的工厂设计模式
    .Linux基础正则表达式字符
    GNSS技术在交通运输领域的创新应用
    MotoGP Ignition:准备好参加 Spotlight 活动!
    SeeOD应用:He-Ne激光束聚焦物镜设计
    Mysql第四篇---数据库索引优化与查询优化
    jvm内存溢出溯源
    延时队列java
  • 原文地址:https://blog.csdn.net/2302_77698668/article/details/132897071