P1596 [USACO10OCT] Lake Counting S 题解


这篇题解是这道题的DFS和BFS解法的介绍
这道题主要有两种解法,深搜和广搜。很多人只会拿DFS写,那我来写写这两种解题方法,再分析一下深搜和广搜的优缺点
首先,看看DFS
其实DFS就是一口气往一个方向搜索,然后遇到障碍之后再改一个方向搜索
优点:好写,不易出错,浅显易懂
缺点:往一个方向查找耗时,当寻找最优解时没有剪枝会卡时间
核心代码:

void dfs(int x,int y){
    a[x][y]='.';//标记为已走
    int dx,dy;
    for(int i=-1;i<=1;i++){//搜索周围的地方
        for(int j=-1;j<=1;j++){
            dx=x+i;
            dy=y+j;
            if(dx>=0&&dx<=n&&dy>=0&&dy<m&&a[dx][dy]=='W'){//如果没有超过边界且为'W'的话就往那个点继续深入搜索
                dfs(dx,dy);
            }
        }
    }
    return;//在void中return为返回上一值,表示如果不能继续深搜就返回上面的点继续搜索
} 


所以,有了这组代码整个代码就写出来了

#include<cstdio>
using namespace std;
char a[101][101];
int ans;
int n,m;
void dfs(int x,int y){
    a[x][y]='.';
    int dx,dy;
    for(int i=-1;i<=1;i++){
        for(int j=-1;j<=1;j++){
            dx=x+i;
            dy=y+j;
            if(dx>=0&&dx<=n&&dy>=0&&dy<m&&a[dx][dy]=='W'){
                dfs(dx,dy);
            }
        }
    }
    return;
} 
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++){
        scanf("%s",a[i]);//避免换行带来问题这里直接读入字符串
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]=='W'){//如果是W的话就直接开始遍历
                dfs(i,j);
                ans++;//水潭加一处
            }
        }
    }
    printf("%d",ans);
    return 0;
}


显然 ,dfs的好处就是好打、方便
那么,再过来看看BFS
BFS就是维护一个队列,以一个点往四周搜索,如果符合条件的话就把它放进队列里
优点:同级优先搜索,在求最优解的时候可以避免许多无用的搜索,提高效率、可以避免递归
缺点:不好写,易出问题,用stl写队列很慢
当我们用stl写队列时的BFS核心代码

void bfs(int x,int y){
    s[x][y]='.';
    int dx,dy;
    for(int i=-1;i<=1;i++){
        for(int j=-1;j<=1;j++){
            dx=x+i;
            dy=y+j;
            if(dx>=0&&dx<n&&dy>=0&&dy<m&&s[dx][dy]=='W'){
                hori.push(dx);//把行放入队列
                para.push(dy);//把列放入队列
            }//注意,其实可以用一个队列维护,但是用两个队列更好写,更直观
        }
    }
}


那么,整体代码就稍微有点差别

#include<cstdio>
#include<queue>
using namespace std;
queue<int>hori;//行的队列
queue<int>para;//列的队列
int n,m;
int ans;
char s[101][101];
inline int read(){//读入优化,可以加快数字的输入
    char p=0;int r=0,o=0;
    for(;p<'0'||p>'9';o|=p=='-',p=getchar());
    for(;p>='0'&&p<='9';r=(r<<1)+(r<<3)+(p^48),p=getchar());
    return o?(~r)+1:r;
}
inline void bfs(int x,int y){//不用递归时可以加inline,提高1ms的运行速度
    s[x][y]='.';
    int dx,dy;
    for(int i=-1;i<=1;i++){
        for(int j=-1;j<=1;j++){
            dx=x+i;
            dy=y+j;
            if(dx>=0&&dx<n&&dy>=0&&dy<m&&s[dx][dy]=='W'){
                hori.push(dx);
                para.push(dy);
            }
        }
    }
}
int main(){
    n=read();m=read();//看不懂的话可以把这一行改成cin或scanf
    for(int i=0;i<n;i++){
        scanf("%s",s[i]);
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(s[i][j]=='W'){
                hori.push(i);
                para.push(j);
                while(!hori.empty()){//如果队列不为空
                    bfs(hori.front(),para.front());//广搜队列前面的元素
                    hori.pop();para.pop();//弹出元素
                }
                ans++;
            }
        }
    }
    printf("%d",ans);
    return 0;
}


值得一提的是,加上快读等优化以后已经做到stl队列能运行时间的极致了,然而提交就算开O2优化还是会有两个测试点被T
这就需要我们手写队列了以及各种优化了,但是这个代码适合bfs的初学者理解

相关推荐

  1. P1596 [USACO10OCT] Lake Counting S 题解

    2024-05-04 16:24:02       11 阅读
  2. 【洛谷题解P1696 [USACO18JAN] Blocked Billboard II B

    2024-05-04 16:24:02       13 阅读
  3. P1697 [USACO18JAN] Lifeguards B 题解

    2024-05-04 16:24:02       28 阅读
  4. P1536 村村通题解

    2024-05-04 16:24:02       23 阅读
  5. 题解】洛谷 P9183 [USACO23OPEN] FEB B

    2024-05-04 16:24:02       39 阅读
  6. P1595 信封问题

    2024-05-04 16:24:02       29 阅读
  7. USACO 2024 Jan B题解

    2024-05-04 16:24:02       36 阅读
  8. P1597 语句解析(C++)

    2024-05-04 16:24:02       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-04 16:24:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-04 16:24:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-04 16:24:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-04 16:24:02       20 阅读

热门阅读

  1. 深入探索Element-UI:构建高效Web前端的利器

    2024-05-04 16:24:02       13 阅读
  2. 消费者——生产者

    2024-05-04 16:24:02       15 阅读
  3. dart-sdk 安装以及vscode开发工具安装dart

    2024-05-04 16:24:02       12 阅读
  4. String str = new String(“Hello, World!“);

    2024-05-04 16:24:02       11 阅读