返回题解分享
讨论 / 题解分享/ 帖子详情

岛屿个数(编程题) - 题解

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

const int N = 55;
#define pii pair<int, int>
#define ft first
#define sd second

int dx[8] = {-1, 0, 1, 0, -1, -1, 1, 1};//八个方向
int dy[8] = {0, 1, 0, -1, -1, 1, 1, -1};

char g[N][N];//地图
int t[N][N], st[N][N];//标记已访问过的点
int n, m, res;//n,m表示行列,res用来记录满足条件的连通块数目

//用于搜索连通块
void bfs(int i, int j) {
    queue<pii> q;//用于储存待访问的点
    q.push({i, j});
    while (!q.empty()) {
        int x = q.front().ft, y = q.front().sd;
        q.pop();
        if (t[x][y]) continue;
        t[x][y] = true;
        for (int i = 0; i < 8; i++) {
            int xx = x + dx[i], yy = y + dy[i];
            if (t[xx][yy] || xx < 1 || xx > n || yy < 1 
            || yy > m || g[xx][yy] == '0') continue;
            q.push({xx, yy});
        }
    }
}

//用于检查连通块是否与边界连接
bool check(int i, int j) {
    queue<pii> q;
    q.push({i, j});
    while (!q.empty()) {
        int x = q.front().ft, y = q.front().sd;
        q.pop();
        if (st[x][y]) continue;
        st[x][y] = true;
        if (x == 1 || x == n || y == 1 || y == m) return true;
        for (int i = 0; i < 4; i++) {
            int xx = x + dx[i], yy = y + dy[i];
            if (st[xx][yy] || g[xx][yy] == '1') continue;
            q.push({xx, yy});
        }
    }
    return false;
}

void solve() {
    memset(t, 0, sizeof t);
    res = 0;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> g[i][j];
        }
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (!t[i][j] && g[i][j] == '1') {
                bfs(i, j);
                memset(st, 0, sizeof st);//初始化边界标记数组
                if (check(i, j)) res++;//检查当前连通块是否与边界相连接,并更新结果
            }
        }
    }

    cout << res << endl;
}

int main() {
    int T;
    cin >> T;
    while(T--) solve();
    return 0;
}
0 回复 0 转发 0 喜欢 3 阅读
回复 (0)
默认 最新
暂无回复,快来抢沙发!