题目链接:​​The Labyrinth​

题目大意:给你一张图,里面只有 * 和 . 两种符号,然后叫你去看 * 附近有多少个 . 加上一,既是找周围与这个 * 联通的 . 有多少个,并把这个 * 变成那个值加一, . 保持不变

题目思路:首先我们考虑写普通做法,既找到一个 * 然后就开始搜,我们发现数据范围为1000*1000,那么可见直接爆搜是不行的,所以我们可以预先保存一下每个联通块里面 . 的数量,然后直接找到 * 附近的四个方向可能的联通块,加起来即可,重复的情况用set判重,用一个数组标记不行,因为每次都要清空,所以就TLE了

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1005;

char mp[maxn][maxn];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int n,m,cnt[maxn*maxn],mark[maxn][maxn];
set<int>s;
set<int>::iterator it;

bool check(int x,int y){
if(x < 0||x >= n||y < 0||y >= m) return false;
return true;
}

void dfs(int x,int y,int id){
mark[x][y] = id;
cnt[id]++;
int dx,dy;
for(int i = 0;i < 4;i++){
dx = x+dir[i][0];dy = y+dir[i][1];
if(check(dx,dy)&&!mark[dx][dy]&&mp[dx][dy] != '*'){
dfs(dx,dy,id);
}
}
}

int main(){
while(~scanf("%d%d",&n,&m)){
memset(mark,0,sizeof(mark));
memset(cnt,0,sizeof(cnt));
s.clear();
for(int i = 0;i < n;i++)
scanf("%s",mp[i]);
int id = 0;
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++)
if(mp[i][j] == '.'&&!mark[i][j]) dfs(i,j,++id);
for(int i = 0;i < n;i++){
for(int j = 0;j < m;j++){
if(mp[i][j] == '.') printf(".");
else{
int sum = 0;
for(int k = 0;k < 4;k++){
int next_x = i+dir[k][0];
int next_y = j+dir[k][1];
if(check(next_x,next_y)&&mp[next_x][next_y] != '*')
s.insert(mark[next_x][next_y]);
}
for(it = s.begin();it != s.end();it++)
sum += cnt[*it];
s.clear();
sum++;
printf("%d",sum%10);
}
}
puts("");
}
}
return 0;
}