1099 PIPI的油田
-
描述: PIPI承包了一大片土地,PIPI打了几个油井,发现这片土地的下面有很多地方埋藏着石油,如果一个油井与另一个油井在上,下,左,右,左上,右下,右上,左下这八个方向中的任意一个方向连通,我们就认为这两个油井属于同一个油田。
现在这块土地可以看成是一个n*m的方格矩阵,标记为’@‘的方格代表一个油井,标记为’*'的方格代表一块贫瘠的土地。你能告诉PIPI他的这块土地上有几个油田吗? -
输入:输入包含多组测试样例。
对于每组测试样例,输入的第一行是两个正整数 n,m (1<=n,m<=100)
接下来输入的一个n*m的方格矩阵,代表PIPI承包土地。
以 0 0结尾结束输入。 -
输出:对于每组测试样例,输出一行,代表土地上油田的数目。
-
输入示例
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
-
输出示例
0 1 2 2
-
代码块
#include <bits/stdc++.h> using namespace std; const int N = 100; int f[N*N];//并查集 int getFather(int x){ // if(x == f[x]) return x; // else{ // f[x] = GetFather(f[x]);//父节点设为根节点 // return f[x];//返回父节点 // } return x==f[x]?x:f[x]=getFather(f[x]);//路径压缩 } int dx[] = {1, 1, 1, -1, -1, -1, 0, 0}; int dy[] = {0, -1, 1, 0, 1, -1, 1, -1};//方向数组 char mp[N][N];//地图 int main(){ int i, j, n, m; while(~scanf(" %d %d", &n, &m)){ if(n == 0 && m == 0) break; int cnt = n*m; for(i=0; i<n; i++){ scanf("%s", mp[i]); } for(i=0; i<cnt; i++) f[i] = i;//初始化 for(i=0; i<n; i++){ for(j=0; j<m; j++){ if(mp[i][j] == '*'){ cnt--;//土地直接让连同分量减一 }else{ for(int k=0; k<8; k++){ int nx = i+dx[k];//新的横坐标 int ny = j+dy[k]; if(nx>=0 && nx<n && ny>=0 && ny<m && mp[nx][ny] == '@'){ int fx = getFather(i*m+j); int fy = getFather(nx*m+ny); if(fx != fy){ cnt--; f[fx] = fy;//合并 } } } } } } printf("%d\n", cnt); } }