当前位置: 代码迷 >> 综合 >> Flood Fill算法(洪水灌溉算法)
  详细解决方案

Flood Fill算法(洪水灌溉算法)

热度:0   发布时间:2023-11-26 11:56:08.0

有两种顺序:

①BFS(最短距离)

(涂的是陆地)

宽搜的是一圈圈的跑

伪代码:

while (队列非空){取出队头 t枚举 t周围的4个邻格if (格子是陆地, 并且格子没有吧被遍历过){标记当前格子被用插入队列}}

例题: 

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

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

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

输入格式

输入包括多个数据集合。

每个数据集合的第一行是两个整数 WW 和 HH,分别表示 xx 方向和 yy 方向瓷砖的数量。

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

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

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

输出格式

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

数据范围

1≤W,H≤201≤W,H≤20

输入样例:

6 9 
....#. 
.....# 
...... 
...... 
...... 
...... 
...... 
#@...# 
.#..#. 
0 0

输出样例:

45

代码1:(BFS) 

#include<iostream>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>#define x first
#define y second
using namespace std;typedef pair<int,int> PII;const int N=25;int n,m;char g[N][N];int bfs(int sx,int sy)  //宽搜写法{queue<PII> q;q.push({sx,sy});g[sx][sy]='#';int res=0;  //当前满足但是在while才加  int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};while(q.size()){res++;PII t=q.front();q.pop();for(int i=0;i<4;i++){int x1=t.x+dx[i],y1=t.y+dy[i];if(x1<0 || x1>=n || y1<0 || y1>=m || g[x1][y1]!='.') continue;g[x1][y1]='#';q.push({x1,y1});}}return res;}int main()
{while(cin>>m>>n,n||m){for(int i=0;i<n;i++) scanf("%s",g[i]);int x1,y1;for(int i=0;i<n;i++)for(int j=0;j<m;j++)if(g[i][j]=='@'){x1=i;y1=j;}cout<<bfs(x1,y1)<<endl;}return 0;
}

②DFS(可能 爆栈 (1M由于递归可能会,256一般不会),更方便)

(每个格子都按照上右下左的顺序看,只要当在某一个方向第一次碰到符合的就到这个格子继续重复) 

dfs(x,y)
{将(x,y)标记为已走枚举(x,y)的4个邻点if 邻点可走dfs(此点)
}

题目:同上

代码:

#include<iostream>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>#define x first
#define y second
using namespace std;typedef pair<int,int> PII;const int N=25;int n,m;char g[N][N];int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};int dfs(int x1,int y1)  //深搜写法{int res=1;  //当前可以g[x1][y1]='#';for(int i=0;i<4;i++){int a=x1+dx[i],b=y1+dy[i];if(a>=0 &&a<n&& b>=0 && b<m &&g[a][b]=='.')  //符合条件res+=dfs(a,b);  //不能用+1,要回溯}return res;}int main()
{while(cin>>m>>n,n||m){for(int i=0;i<n;i++) scanf("%s",g[i]);int x1,y1;for(int i=0;i<n;i++)for(int j=0;j<m;j++)if(g[i][j]=='@'){x1=i;y1=j;}cout<<dfs(x1,y1)<<endl;}return 0;
}

  相关解决方案