【题解】降水
思路:
枚举每一层(层数要取所有高度中最高的)。设当前枚举到了第 $i$ 层:
STEP 1:则遍历所有点,把高度高于或等于 $i$ 的点标记为 $1$,反之,标记为 $0$。
STEP 2 : 然后找出被 $1$ 包围的 $0$ 的个数(用 dfs),加到 $ans$ 里。最后输出 $ans$ 即可。
对于 STEP 2 来说,把四周的点作为起点,进行 dfs,只要 visit 过的点就标记为 $1$。最后再遍历一遍所有点,统计 $0$ 的个数。
代码:
#include
using namespace std;
int n,m;
int mapn[109][109];
int nown[109][109];
int maxn = -1;
int ans=0;
int nexts[10][3] = {{0,1},{1,0},{0,-1},{-1,0}};
void dfs(int r,int c){
nown[r][c] = 1;
int nr,nc;
for(int i=0; i<4; i++){
nr = r+nexts[i][0];
nc = c+nexts[i][1];
if(nr > n || nr < 1 || nc > m || nc < 1 || nown[nr][nc] == 1)continue;
nown[nr][nc] = 1;
dfs(nr,nc);
}
}
void func(){
for(int i=1; i<=m; i++)
if(nown[1][i] == 0)dfs(1,i);
for(int j=1; j<=n; j++){
if(nown[j][1] == 0)dfs(j,1);
if(nown[j][m] == 0)dfs(j,m);
}
for(int i=1; i<=m; i++)
if(nown[n][i] == 0)dfs(n,i);
}
int main(){
cin >> n >> m;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
cin >> mapn[i][j];
maxn = max(mapn[i][j],maxn);
}
}
for(int l=1; l<=maxn; l++){//枚举每一层
int tmp = 0;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
if(mapn[i][j] >= l) nown[i][j] = 1;
else nown[i][j] = 0;
}
}
func();
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(nown[i][j] == 0)
ans++;
}
cout << ans;
return 0;
}