1 条题解

  • 0
    @ 2023-8-31 15:15:33

    用 vis 记录每个位置算没算过

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1500;
    int n, m;
    char a[MAXN + 5][MAXN + 5];
    int dx[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    int dy[] = {0, 0, -1, 1, -1, -1, 1, 1};
    // 每个位置有没有被统计过,false 表示没有被统计过
    bool vis[MAXN + 5][MAXN + 5];
    // 广搜的队列
    queue<pair<int, int>> q;
    // 把 (x,y) 相连的 * 全都标记为统计过了
    // 返回有几个星号
    int bfs(int x, int y)
    {
        int cnt = 0; // 统计 * 的数量
        // 起点入队
        q.push(make_pair(x, y));
        vis[x][y] = true;
        cnt++;
        // 只要还有东西要改,就改
        while (!q.empty())
        {
            // 取出队头
            pair<int, int> now = q.front();
            q.pop();
            int nowX = now.first;
            int nowY = now.second;
            // 检查当前位置八连通的所有位置
            for (int i = 0; i < 8; i++)
            {
                int nxtX = nowX + dx[i];
                int nxtY = nowY + dy[i];
                // 在范围内、是 W、没统计过,就继续搜
                if (1 <= nxtX && nxtX <= n &&
                    1 <= nxtY && nxtY <= m &&
                    a[nxtX][nxtY] == '*' &&
                    vis[nxtX][nxtY] == false)
                {
                    q.push(make_pair(nxtX, nxtY));
                    vis[nxtX][nxtY] = true;
                    cnt++;
                }
            }
        }
        return cnt;
    }
    
    // num[i] 统计大小为 i 的连通块有几个
    int num[100000 + 5];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                cin >> a[i][j];
    
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                if (a[i][j] == '*' && !vis[i][j])
                {
                    // 计算这个连通块的大小
                    // 并且都标记为算过了
                    int now = bfs(i, j);
                    num[now]++;
                    // cout << now << " ";
                }
            }
        }
    
        int ans1 = 0; // 统计星系数量
        int ans2 = 0; // 记录最大星系大小
        for (int i = 1; i <= 100000; i++)
        {
            if (num[i] == 0)
                continue;
            // 有 num[i] 个大小为 i 的星座,构成了一个星系
            ans1++;
            ans2 = max(ans2, num[i] * i); // 当前星系大小
        }
        cout << ans1 << " " << ans2 << "\n";
        return 0;
    }
    

    直接把星星改成 .

    #include <bits/stdc++.h>
    using namespace std;
    int n, m;
    char g[1505][1505];
    int cnt[100005]; //大小为i的星座,出现了几次
    //把 (sx,sy) 对应的连通块大小返回,并把所有星星删掉
    int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};
    int dy[] = {1, -1, 0, 0, 1, -1, 1, -1};
    queue<pair<int, int>> q;
    int bfs(int sx, int sy)
    {
        int res = 1;
        q.push(make_pair(sx, sy));
        while (!q.empty())
        {
            pair<int, int> now = q.front();
            q.pop();
            for (int i = 0; i < 8; i++)
            {
                int nx = now.first + dx[i];
                int ny = now.second + dy[i];
                if (1 <= nx && nx <= n &&
                    1 <= ny && ny <= m &&
                    g[nx][ny] == '*')
                {
                    res++;
                    g[nx][ny] = '.';
                    q.push(make_pair(nx, ny));
                }
            }
        }
        return res;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(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 (g[i][j] == '.')
                    continue;
                //当前点是一个星星
                g[i][j] = '.';
                int now = bfs(i, j); //当前点对应的连通块大小
                cnt[now]++;
            }
        //统计答案
        int ans1 = 0; //星系数量
        int ans2 = 0; //最大星系大小
        for (int i = 1; i <= 100000; i++)
        {
            //所有大小为 i 的星座构成了一个星系
            //大小为 i 的星座有 cnt[i] 个
            //星系大小:i*cnt[i]
            if (cnt[i] > 0)
            {
                ans1++;
                ans2 = max(ans2, i * cnt[i]);
            }
        }
        cout << ans1 << " " << ans2 << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    1322
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    18
    已通过
    8
    上传者