细胞统计学习总结

//刚开始接触"细胞统计"这道题时是在学习栈和队列时接触的,但是经过知识的拓展,我又掌握了用并查集解决此题的算法,下面是我给出的题目和代码。
//一矩形阵列由数字0到9组成,数字1到9代表细胞,
//细胞的定义为沿细胞数字上下左右还是细胞数字
//则为同一细胞,求给定矩形阵列的细胞个数。
//如阵列:
//4 10
//0 2 3 4 5 0 0 0 6 7
//1 0 3 4 5 6 0 5 0 0
//2 0 4 5 6 0 0 6 7 1
//0 0 0 0 0 0 0 0 8 9
//有4个细胞。
//输入:整数m,n(m行,n列<=3000)
//m*n的矩阵;
//输出:细胞的个数


//深度优先搜索 DFS
#include <iostream>
using namespace std;
const int maxn = 3005;
int m,n;
int a[maxn][maxn]={0};
int d[4][2] = {0,1,1,0,0,-1,-1,0};
int DFS(int x,int y) {
    int sx,sy;
    a[x][y]=0;
    for(int i = 0;i < 4; i++) {
        sx = x + d[i][0];
        sy = y + d[i][1];
        if (a[sx][sy] != 0&& sx >= 0&& sx < m && sy >= 0 && sy < n)
            DFS(sx,sy);
    }
}
int main() {
    int ans = 0;
    cin >> m >> n;
    for (int i = 0;i < m; i++) {
        for (int j = 0;j < n; j++) {
            cin >> a[i][j];
        }
    }
    for (int i = 0;i < m; i++) {
        for (int j = 0;j < n; j++) {
            if (a[i][j] != 0) {
                ans++;
                DFS(i,j);
            }
        }
    }
    cout << ans << endl;
}


//广度优先搜索 BFS
#include <queue>
#include <iostream>
using namespace std;
const int maxn = 3005;
queue <int> qx,qy;
int m,n;
int a[maxn][maxn] = {0};
int d[4][2] = {0,1,1,0,0,-1,-1,0};
int BFS () {
    int x,y,sx,sy;
    while(!qx.empty()){
        x = qx.front();
        y = qy.front();
        qx.pop();
        qy.pop();
        for (int i = 0;i < 4; i++) {
            sx = x + d[i][0];
            sy = y + d[i][1];
            if (sx >= 0 && sx < m && sy >= 0 && sy < n && a[sx][sy]) {
                qx.push(sx);
                qy.push(sy);
                a[sx][sy] = 0;
            }
        }
    }
}
int main() {
    int ans=0;
    cin >> m >> n;
    for (int i = 0;i < m; i++) {
        for (int j = 0;j < n; j++) {
            cin >> a[i][j];
        }
    }
    for (int i = 0;i < m; i++) {
        for (int j = 0;j < n; j++) {
            if (a[i][j] != 0) {
                ans++;
                qx.push(i);
                qy.push(j);
                BFS();
            }
        }
    }
    cout << ans << endl;
}


//并查集
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1000;
class record {
public:
    int x;
    int y;
};
record a[maxn][maxn],p,q;
int b[maxn][maxn]={0};
record find(int i,int j) {
    if (a[i][j].x == i && a[i][j].y == j) return a[i][j];
    record pos = find (a[i][j].x,a[i][j].y);
    a[i][j] = pos;
    return pos;
}
int main() {
    int m,n;
    cin >> m >> n;
    for (int i = 0;i < m; i++) {
        for (int j = 0;j < n; j++) {
            cin >> b[i][j];
        }
    }
    for (int i = 0;i < m; i++) {
        for (int j = 0;j < n; j++) {
            if (b[i][j]) {
                a[i][j].x = i;
                a[i][j].y = j;
            }
        }
    }
    for (int i = 0;i < m; i++) {
        for (int j = 0;j < n; j++) {
            if (b[i][j]) {
                if (b[i+1][j]) {
                    p = find (i,j);
                    q = find (i+1,j);
                    if (p.x != q.x || p.y !=q.y) {
                        a[q.x][q.y] = p;
                    }
                }
                if (b[i][j+1]) {
                    p = find (i,j);
                    q = find (i,j+1);
                    if (p.x != q.x || p.y !=q.y) {
                        a[q.x][q.y] = p;
                    }
                }
            }
        }
    }
    int tot=0;
    for(int i=0;i<m;i++)
       for (int j=0;j<n;j++)
          if ((a[i][j].x==i)&&(a[i][j].y==j)&&b[i][j]) tot++;
    cout << tot << endl;
}

 

posted @ 2014-02-15 20:17  闪光阳  阅读(950)  评论(0编辑  收藏  举报