## [$AcWing$ $1113$. 红与黑](https://www.acwing.com/problem/content/1115/) ### 一、题目描述 有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。 你站在其中一块 **黑色的瓷砖** 上,只能向相邻( **上下左右** 四个方向)的 **黑色** 瓷砖移动。 请写一个程序,计算你总共能够到达多少块黑色的瓷砖。 **输入格式** 输入包括多个数据集合。 每个数据集合的第一行是两个整数 $W$ 和 $H$,分别表示 $x$ 方向和 $y$ 方向瓷砖的数量。 在接下来的 $H$ 行中,每行包括 $W$ 个字符。每个字符表示一块瓷砖的颜色,规则如下 1)‘.’:黑色的瓷砖; 2)‘#’:红色的瓷砖; 3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。 当在一行中读入的是两个零时,表示输入结束。 **输出格式** 对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。 **数据范围** $1≤W,H≤20$ **输入样例**: ```cpp {.line-numbers} 6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 0 0 ``` **输出样例**: ```cpp {.line-numbers} 45 ``` ### 二、$dfs$ ```cpp {.line-numbers} #include using namespace std; const int N = 25; // dfs 实现flood fill 算法 int n, m; char g[N][N]; bool st[N][N]; int dx[] = {-1, 0, 1, 0}; int dy[] = {0, 1, 0, -1}; int cnt; void dfs(int x, int y) { // x,y贡献了1个结点数 cnt++; st[x][y] = true; for (int i = 0; i < 4; i++) { int tx = x + dx[i], ty = y + dy[i]; if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue; if (g[tx][ty] != '.') continue; if (st[tx][ty]) continue; dfs(tx, ty); } } int main() { while (cin >> m >> n, n || m) { // 先输入列数,再输入行数,小坑 // 多组测试数据 memset(st, 0, sizeof st); cnt = 0; // 找起点 int x, y; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { cin >> g[i][j]; if (g[i][j] == '@') x = i, y = j; } dfs(x, y); printf("%d\n", cnt); } return 0; } ``` ### 三、$bfs$ ```cpp {.line-numbers} #include using namespace std; const int N = 30; struct Node { int x; int y; }; char g[N][N]; int n, m; int dx[] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; bool st[N][N]; int cnt; void bfs(int x, int y) { queue q; q.push({x, y}); while (q.size()) { Node t = q.front(); q.pop(); cnt++; for (int i = 0; i < 4; i++) { int tx = t.x + dx[i], ty = t.y + dy[i]; if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue; if (st[tx][ty]) continue; if (g[tx][ty] != '.') continue; st[tx][ty] = true; q.push({tx, ty}); } } } int main() { while (cin >> m >> n, n || m) { memset(st, 0, sizeof st); cnt = 0; int x, y; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> g[i][j]; if (g[i][j] == '@') x = i, y = j; } } bfs(x, y); printf("%d\n", cnt); } return 0; } ```