题目大意: 求字符矩阵中, 对于任意一个 ‘*’ 字符, 如果将其变为‘ . ’ ,在其周围将会有对少个 ‘ . ’ 联通, 最后 输出, 如果符号是‘ . ’ 就输出‘ . ’ 否则输出 联通个数的个位数!
解题思路:首先初始化一个搜索值 bit = 1; 先遍历每一个点, 如果该点位置处是 ‘ . ’ 则对其 dfs(i,j, bit) ; 用数组记录每一次搜索的搜索值; 并求出每一个‘ . ’点 可以与之相连的‘ . ’ 的个数, 最后对于每一个‘ * ’ 将其周围四个方向(不重复) 的‘ . ’ 的值加起来!
我的代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 100;
char mapp[maxn][maxn]; //存储矩阵
int dir[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};//方向数组
int vis[maxn][maxn]; //访问记录数组
int has[maxn * maxn]; //记录总共出现的次数的数组
int sum[maxn][maxn]; // 每个‘.’的值
int n,m;
int dfs(int x, int y, int dep) {
sum[x][y] = dep;
//printf("x = %d y = %d\n", x, y);
for(int i = 0; i < 4; i++) {
int xx = x + dir[i][0];
int yy = y + dir[i][1];
//printf("%d %d\n", xx, yy);
if(xx >= 1 && xx <= n && yy >=1 && yy <= m && mapp[xx][yy] == '.' && !vis[xx][yy]) {
vis[xx][yy] = 1;
dfs(xx, yy, dep);
//这里记得vis不用置为0
}
}
return 0;
}
int main() {
//freopen("in.txt", "r", stdin);
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%s", mapp[i] + 1);
int deep = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(mapp[i][j] == '.' && !sum[i][j]) {
dfs(i, j, deep);
deep++;
}
}
}
// dfs(1, 3, 1);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(sum[i][j])
has[sum[i][j]]++;
}
}
set<int> tem;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(mapp[i][j] == '*') {
tem.insert(sum[i][j - 1]);
tem.insert(sum[i][j + 1]);
tem.insert(sum[i - 1][j]);
tem.insert(sum[i + 1][j]);
int len = tem.size();
int all = 0;
set<int> :: iterator it = tem.begin();
for(it ; it != tem.end(); it++) {
all += has[*it];
}
all += 1;
printf("%d", all%10);
tem.clear();
} else
printf("%c", mapp[i][j]);
}
printf("\n");
}
}