フラッドフィル
主にグリッドグラフ計算のためのフラッドフィルアルゴリズム(中国語名:フラッド灌漑アルゴリズム)は、接続されたブロックを見つけます。
BFS(ワイド検索)とDFS(ディープ検索)の2つの方法を採用しています。BFSは最短パスを見つけるためによく使用され、DFSはフラッドフィルの問題を解決するのに便利です。
1113を取得します。赤と黒
床に赤と黒の正方形のタイルが付いた長方形の家があります。
あなたは黒いタイルの1つに立っており、隣接する黒いタイル(上、下、左、右)にのみ移動できます。
合計で到達できる黒いタイルの数を計算するプログラムを作成してください。
入力フォーマット
入力には複数のデータセットが含まれます。
各データセットの最初の行は、2つの整数WWとHHであり、それぞれxx方向とyy方向のタイルの数を表します。
次のHH行では、各行にWW文字が含まれています。各文字はタイルの色を表します。ルールは次のとおりです。
1) '。':黒いタイル;
2) '#':赤いタイル;
3) '@':黒いタイル、そしてあなたはこのタイルの上に立っています。この文字は、各データセットに1回だけ表示されます。
2つのゼロが連続して読み取られる場合、それは入力が終了したことを意味します。
出力フォーマット
データセットごとに、行を個別に出力し、初期位置から到達できるタイルの数を示します(カウント時の初期位置のタイルを含む)。
データ範囲
1≤W、H≤201≤W、H≤20
入力サンプル:
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
0 0
サンプル出力:
45
回答:
DFSソリューション
//深搜写法
#include<iostream>
#include<algorithm>
#define x first
#define y second
using namespace std;
const int N = 25;
int n,m;
char g[N][N];
int dx[] = {
-1,0,1,0}, dy[] = {
0,1,0,-1};
int dfs(int x, int y)
{
int res = 1;
g[x][y] = '#';//将走过的标记为障碍物表示已经走过
for(int i = 0; i < 4; i ++)
{
int a = x + dx[i], b = y + dy[i];
if(a >= 0 && a < n && b >= 0 && b < m && g[a][b] == '.')
{
res += dfs(a,b);
}
}
return res;
}
int main()
{
while(cin >> m >> n, n || m)
{
for(int i = 0; i < n; i ++ )cin >> g[i];
int x,y;
for(int i = 0; i < n; i ++)
for(int j = 0; j < m; j ++)
if(g[i][j] == '@')
{
x = i;y = j;
}
cout << dfs(x,y) << endl;
}
return 0;
}
BFSソリューション
//BFS宽搜写法
#include<iostream>
#include<queue>
#include<algorithm>
#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[] = {
-1,0,1,0}, dy[] = {
0,1,0,-1};//上右下左
int bfs(int sx, int sy)
{
queue<PII> q;
q.push({
sx,sy}); //将起点放入队列中
g[sx][sy] = '#';//起点走过了标记为障碍物表示不能再走
int res = 0;//表示所有能够搜到的点的数量
while(q.size())//当队列不空的时候,取队列头元素
{
auto t = q.front();
q.pop();
res++;//记录走过的点的个数
for(int i = 0; i < 4; i ++) //枚举四个方向
{
int x = t.x + dx[i], y = t.y + dy[i];
if(x < 0 || x >= n || y < 0 || y >= m || g[x][y] != '.' )continue;
g[x][y] = '#';//将该点设置为障碍物,表示已经走过
q.push({
x,y});//再将当点存进队列里,用作下一循环继续向四周扩散
}
}
return res;
}
int main()
{
while(cin >> m >> n, n || m)
{
for(int i = 0; i < n; i ++)
cin >> g[i];
int x, y;
for(int i = 0; i < n; i ++)
for(int j = 0; j < m; j ++)
if(g[i][j] == '@')
{
x = i;y = j;
}
cout << bfs(x,y) << endl;
}
return 0;
}