链接:https://ac.nowcoder.com/acm/contest/218/A
来源:牛客网
现在,你作为一名新星鹏洛客,找到了一块绝佳的修炼地。这块地方可以被描述成一个 n x m 的矩形。你已经在这块地中的一些位置打好了标记。接下去,就该对整块地赋予你的颜色了。一个位置能被赋予你的颜色,当且仅当满足以下条件之一:
1. 这个位置被打上了标记。
2. 这个位置在不经过被打标记的位置的情况下与边界不连通(这个图是四联通的)。换句话说,如果你从这个位置开始,在不经过被打标记的位置,且只能向上下左右四个方向移动的情况下永远不能走到地图的边界,那么这个位置符合条件。
现在,你的好基友想知道,你能为多少个位置赋予你自己的颜色呢?
输入描述:
第一行包含两个正整数 n, m ,表示地图的长和宽。
接下去 n 行,每行一个长为 m 的字符串,表示地图的一行。
其中 表示该位置未被打标记; 表示该位置被打了标记。
保证地图仅由 和 构成。
输出描述:
输出仅一行,包含一个整数,表示你的答案。
示例1
输入
复制
4 4
…
.###
.#.#
.###
输出
复制
9
备注:
1 ≤ n x m ≤ 10^6
逆向思考:从四条边上的点出发开始搜,这些点能到达的点都一定不符合题意
这里有个开数组的方式就是n*m <= 10^6 行列不知道多大,那就用string去开空间
#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6+5;
string map[N];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int n, m;
int ans = 0;
void DFS(int x, int y) {
if (map[x][y] == '#') return;
map[x][y] = '#'; // 不放到下面的if里是因为这里可以判断开始搜索的的位置是否符合条件
ans++;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0&& ny < m) {
DFS(nx, ny);
}
}
}
int main() {
scanf("%d%d", &n, &m);
ans = 0;
for (int i = 0; i < n; i++) cin >> map[i];
for (int i = 0; i < n; i++) {
DFS(i, 0);
DFS(i, m-1);
}
for (int j = 0; j < m; j++) {
DFS(0, j);
DFS(n-1, j);
}
cout << n*m - ans << "\n";
return 0;
}