題目鏈接:https://vjudge.net/problem/CodeForces-616C#author=0
思路:bfs'.',這樣就可以把聯通在一起的'.',和成一個聯通塊,計算出'.'的個數,然後把這個聯通塊標號,放入mp中,最後遍歷矩陣時,當遇到'*',就把上下左右四個方向上不同的聯通塊代表的數量加起來。
代碼:
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
const int N = 1010;
int n, m, cnt, ans[N][N];
char tu[N][N];
bool vis[N][N];
map<int, int> mp, book;
struct node {
int x, y;
node(){}
node(int x_, int y_) {
this->x = x_;
this->y = y_;
}
};
void bfs(int x, int y) {
int sum = 1;
vis[x][y] = 1;
queue<node> q;
q.push(node(x, y));
node tmp;
int nxt[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
int tx, ty;
while(!q.empty()) {
tmp = q.front();
q.pop();
ans[tmp.x][tmp.y] = cnt;
for(int k = 0; k < 4; k++) {
tx = tmp.x + nxt[k][0];
ty = tmp.y + nxt[k][1];
if(tx < 1 || tx > n || ty < 1 || ty > m)
continue;
if(vis[tx][ty] || tu[tx][ty] == '*')
continue;
vis[tx][ty] = 1;
q.push(node(tx, ty));
sum++;
}
}
mp[cnt] = sum;
}
int main() {
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%s", tu[i] + 1);
cnt = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(tu[i][j] == '.' && !vis[i][j]) {
bfs(i, j);
cnt++;
}
}
}
int sum, tx, ty, nxt[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(tu[i][j] == '.')
printf("%c", tu[i][j]);
else {
sum = 0;
book.clear();
for(int k = 0; k < 4; k++) {
tx = i + nxt[k][0];
ty = j + nxt[k][1];
if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && tu[tx][ty] == '.') {
if(book[ans[tx][ty]] == 0) {
book[ans[tx][ty]] = 1;
sum += mp[ans[tx][ty]];
}
}
}
printf("%d", (sum + 1) % 10);
}
}
printf("\n");
}
return 0;
}