UVa 572 Oil Deposits (Floodfill && DFS)
题意 :输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。如果两个字符“@”所在的格子相邻(横竖以及对角方向),就是说它们属于同一个八连块。
分析 :可以考虑种子填充深搜的方法。两重for循环枚举所有的点,然后只要是@点且还没被染色过则从这个点出发到达相邻的点染成同样的色(这里的颜色可以用不同的数字来表示),然后每一块@的联通块都能通过这种方式求出来,详情可以参考Wiki百科的动画帮助理解=》http://en.widipedia.org/wiki/Floodfill
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h>
using namespace std;
int G[101][101], row, col, seed[101][101], ans = 0;
int Move[8][2] = {
{-1,1},{0,1},{1,1},
{-1,0}, {1,0},
{-1,-1},{0,-1},{1,-1}
};
bool bound(int Row, int Col)
{
if(Row<0 || Col<0 || Row>=row || Col>=col) return true;
else return false;
}
int SEED = 1;
inline void DFS(int Row, int Col)
{
if(!G[Row][Col]) return;
else{
seed[Row][Col] = SEED;
for(int i=0; i<8; i++){
int y = Row + Move[i][0];
int x = Col + Move[i][1];
if(!bound(y, x) && G[y][x] && seed[y][x]==0) DFS(y, x);
}
}
}
int main(void)
{
while(~scanf("%d %d", &row, &col) && (row&&col)){
for(int i=0; i<101; i++){
memset(G[i], false, sizeof(G[i]));
memset(seed[i], 0, sizeof(seed[i]));
}
SEED = 1;
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
char temp; scanf(" %c", &temp);
if(temp=='*') G[i][j] = false;
else G[i][j] = true;
}
}
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
if(G[i][j] && seed[i][j]==0) {DFS(i, j);SEED++;}
}
}
printf("%d\n", SEED-1);
}
return 0;
}
经验 :在dfs中需要往八个方向进行搜索,之前的做法从多个if=》存到move数组利用for循环实现=》现在有一个更简便的方法=》
for(int dr=-1; dr<=1; dr++) for(int dc=-1; dc<=1; dc++){ int y = Row + dr; int x = Col + dc; if(!bound(y, x) && G[y][x] && seed[y][x]==0) DFS(y, x); }