1 条题解

  • 0
    @ 2026-2-17 22:21:45
    #include<bits/stdc++.h>
    using namespace std;
    
    // [1] 常量定义:n最大为1000,预留足够空间
    const int MAXN = 1005;
    // 四个移动方向:上下左右
    int dx[] = {-1, 1, 0, 0};
    int dy[] = {0, 0, -1, 1};
    
    // [2] 全局数组定义
    int mp[MAXN][MAXN];                // 存储迷宫的0/1值
    int block_id[MAXN][MAXN];          // 每个格子所属的连通块编号
    int block_size[MAXN * MAXN];       // 每个连通块的大小(最多1e6个连通块)
    int n, m;                           // 迷宫大小n*n,查询次数m
    
    int main()
    {
        // 关闭cin同步,加速输入输出,应对1e5次查询
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        // [3] 读取迷宫大小和查询次数
        cin >> n >> m;
    
        // [4] 读取n*n的迷宫,使用1-based坐标,和题目输入对应
        for(int i = 1; i <= n; i++)
        {
            string s;
            cin >> s;
            for(int j = 1; j <= n; j++)
            {
                mp[i][j] = s[j-1] - '0'; // 字符串是0-based,转换为1-based坐标
            }
        }
    
        // [5] 初始化连通块编号为0(0表示未访问)
        memset(block_id, 0, sizeof(block_id));
        int block_cnt = 0; // 连通块编号计数器
    
        // [6] 遍历整个迷宫,BFS预处理所有连通块
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                // 如果当前格子未被访问过,启动BFS遍历整个连通块
                if(block_id[i][j] == 0)
                {
                    block_cnt++; // 分配新的连通块编号
                    queue<pair<int, int>> q;
                    q.push({i, j});
                    block_id[i][j] = block_cnt;
                    int cnt = 1; // 记录当前连通块的大小
    
                    // BFS核心循环
                    while(!q.empty())
                    {
                        auto cur = q.front();
                        q.pop();
                        int x = cur.first;
                        int y = cur.second;
    
                        // 遍历四个移动方向
                        for(int k = 0; k < 4; k++)
                        {
                            int nx = x + dx[k];
                            int ny = y + dy[k];
                            // 合法性校验:
                            // 1. 坐标在1~n范围内
                            // 2. 该格子未被访问过
                            // 3. 相邻格子数值不同(符合移动规则)
                            if(nx >= 1 && nx <= n && ny >= 1 && ny <= n && block_id[nx][ny] == 0 && mp[nx][ny] != mp[x][y])
                            {
                                block_id[nx][ny] = block_cnt; // 标记连通块编号
                                cnt++; // 连通块大小+1
                                q.push({nx, ny}); // 入队等待遍历
                            }
                        }
                    }
    
                    // 记录当前连通块的大小
                    block_size[block_cnt] = cnt;
                }
            }
        }
    
        // [7] 处理m次查询,直接查表输出结果
        while(m--)
        {
            int i, j;
            cin >> i >> j;
            // 直接输出当前格子所属连通块的大小
            cout << block_size[block_id[i][j]] << '\n';
        }
    
        return 0;
    }
    
    • 1

    信息

    ID
    1312
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者