题目大致意思就是说给你一个迷宫的地图,让你找到从每一个走不通的地方(*)旁边紧靠着的空地(.)的大小(最后要加上自己,也就是空地的数量加一)
很容易想到使用bfs或者dfs,这里我们就使用dfs遍历每个空地联通块,不能直接暴力记录,会超时,使用标号连通块加set的使用能够减少时间消耗
代码具体实现如下
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n,m;
int cnt;
int mp[N][N];
int ans[N*N]; //mp 该点所属连通块的标号, ans表示该连通块的大小
char g[N][N];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //四个方向
void dfs(int x, int y){
mp[x][y]=cnt; //该点所属联通块的标号
ans[cnt]++; //该连通块的大小加一
for(int i=0 ; i<4 ; i++){
int xx=x+dx[i], yy=y+dy[i];
//超出范围 走不通 已经标号 都跳过下一次递归
if(xx>=n || xx<0 || yy>=m || yy<0 || g[xx][yy]=='*' || mp[xx][yy]!=0) continue;
dfs(xx, yy);
}
}
int main(){
cin>>n>>m;
for(int i=0 ; i<n ; i++) scanf("%s", g[i]);
for(int i=0 ; i<n ; i++)
for(int j=0 ; j<m ; j++){
if(g[i][j] == '.' && mp[i][j]==0){
//每次遇到空的地,标号加一
cnt++;
dfs(i, j);
}
}
for(int i=0 ; i<n ; i++){
for(int j=0 ; j<m ; j++){
if(g[i][j] == '*'){
//set去重
set<int> st;
set<int>::iterator it;
int re=0;
for(int k=0 ; k<4 ; k++){
int xx=i+dx[k], yy=j+dy[k];
if(xx>=n || xx<0 || yy>=m || yy<0 || g[xx][yy]=='*') continue;
//将每个点所属连通块的标号放入set
st.insert(mp[xx][yy]);
}
for(it=st.begin() ; it!=st.end() ; it++) re+=ans[*it];
cout<<(re+1)%10;
}
else cout<<".";
}
cout<<endl;
}
return 0;
}