题目:
多组案例,每组案例输入一个m行n列的字符矩阵,统计字符‘@’组成多少个连通块。如果两个字符‘@’所在的格子相邻(横、竖或对角线),则说明它们属于同一连通块。
代码:
dfs
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int maxn = 105;
char g[maxn][maxn];
int vis[maxn][maxn];
int n, m;
int dir[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
void dfs(int x, int y) {
for(int i=0; i<8; i++) {
int newx = x+dir[i][0];
int newy = y+dir[i][1];
if(!vis[newx][newy] && g[newx][newy]=='@') {
vis[newx][newy]=1;
dfs(newx,newy);
}
}
}
void deal() {
int count = 0;
memset(vis, 0, sizeof(vis));
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(!vis[i][j] && g[i][j]=='@') {
dfs(i, j);
count++;
}
}
}
printf("%d\n", count);
}
int main() {
int i,j;
while(scanf("%d%d", &n, &m) && (n+m)) {
for(i=0; i<n; i++) {
getchar();
for(j=0; j<m; j++) {
scanf("%c", &g[i][j]);
}
}
deal();
}
return 0;
}
bfs
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int maxn = 105;
struct node {
int x, y;
node(int a, int b) {
x = a;
y = b;
}
};
char g[maxn][maxn];
queue<node> v;
int vis[maxn][maxn];
int n, m;
int dir[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
void bfs(int x, int y){
int i, j;
while(!v.empty()) v.pop();
v.push(node(x,y));
while(!v.empty()) {
node mynode = v.front();
v.pop();
for(i=0; i<8; i++) {
int newx = mynode.x+dir[i][0];
int newy = mynode.y+dir[i][1];
if(g[newx][newy]=='@' && !vis[newx][newy]) {
vis[newx][newy] = 1;
v.push(node(newx,newy));
}
}
}
}
void deal() {
memset(vis, 0, sizeof(vis));
int count = 0;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(!vis[i][j] && g[i][j]=='@') {
bfs(i,j);
count++;
}
}
}
printf("%d\n", count);
}
int main() {
int i,j;
while(scanf("%d%d", &n, &m) && (n+m)) {
memset(g, 0, sizeof(g));
for(i=0; i<n; i++) {
getchar();
for(j=0; j<m; j++) {
scanf("%c", &g[i][j]);
}
}
deal();
}
return 0;
}