https://codeforc.es/contest/616/problem/C
找每一个‘.’,把连通的’.‘标上记号,再开一个数组记录带这个记号的’.'块的大小,然后搜‘*’,把上下左右的‘.’的块的大小加起来, 用set去掉重复的块
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<vector>
#include<string.h>
#include<queue>
#include<cmath>
#define mem(a, b) memset(a, b, sizeof(a))
#define LL long long
#define N 1001
#define MOD
using namespace std;
int n, m, ans, dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}}, vis[N][N], cnt=2, value[N*N];
char mapp[N][N];
set<int>s;
void find(int x, int y){
for(int i=0; i<4; i++){
int xx=x+dir[i][0], yy=y+dir[i][1];
if(xx<0||xx>=n||yy<0||yy>=m) continue;
if(mapp[xx][yy]=='.'&&vis[xx][yy]==0){
ans++;
vis[xx][yy]=cnt;
find(xx, yy);
}
}
}
void dfs() {
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(mapp[i][j]=='.'&&vis[i][j]==0) {
vis[i][j]=cnt;
ans=1;
find(i, j);
value[cnt]=ans;
cnt++;
}
}
}
}
int main() {
while(scanf("%d%d",&n, &m)!=EOF) {
mem(vis, 0);
for(int i=0; i<n; i++) {
scanf("%s",mapp[i]);
for(int j=0; j<m; j++){
if(mapp[i][j]!='.')
vis[i][j]=1;
}
}
dfs();
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(mapp[i][j]=='.')
printf(".");
else{
ans=1;
s.clear();
for(int k=0; k<4; k++) {
int xx=i+dir[k][0], yy=j+dir[k][1];
if(xx<0||xx>=n||yy<0||yy>=m) continue;
else if(mapp[xx][yy]=='.'){
s.insert(vis[xx][yy]);
}
}
for(set<int>::iterator h=s.begin(); h!=s.end(); h++)
ans+=value[*h];
printf("%d",ans%10);
}
}
printf("\n");
}
}
}