1 条题解

  • 0
    @ 2026-10-18 18:41:52

    G7004 [GESP202403 七级] 俄罗斯方块 题解

    知识点:洪水填充、形状归一化、集合。

    解题思路

    洪水填充提取每个四连通同值块,以块内第一个按行列出现的格子为原点记录相对坐标,排序后放入形状集合。

    为什么正确

    同形状的平移保留全部相对坐标,排序消除遍历顺序影响;不同坐标集合不能通过平移重合。

    易错点

    只按平移去重,不能自行加入旋转或翻转;不同数值但同形状按题面归为同类。

    复杂度

    设总格数N,时间O(N log N)上界,空间O(N)。

    参考代码(C++17)

    #include<bits/stdc++.h>
    
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n,m;
        cin>>n>>m;
        vector<vector<int>>a(n,vector<int>(m)),vis(n,vector<int>(m));
        for(auto &row:a)for(int &x:row)cin>>x;
        set<vector<pair<int,int>>>types;
        int dr[]= {
            -1,1,0,0
        }
        ,dc[]= {
            0,0,-1,1
        }
        ;
        for(int i=0;i<n;i++)for(int j=0;j<m;j++)if(!vis[i][j]) {
            vector<pair<int,int>>q= {
                {
                    i,j
                }
            }
            ,shape;
            vis[i][j]=1;
            for(int k=0;k<(int)q.size();k++) {
                auto [u,v]=q[k];
                shape.push_back({u-i,v-j});
                for(int z=0;z<4;z++) {
                    int x=u+dr[z],y=v+dc[z];
                    if(x>=0&&x<n&&y>=0&&y<m&&!vis[x][y]&&a[x][y]==a[i][j]) {
                        vis[x][y]=1;
                        q.push_back({x,y});
                    }
                }
            }
            sort(shape.begin(),shape.end());
            types.insert(shape);
        }
        cout<<types.size();
    }
    

    说明

    本题解为配套教学整理,非官方题解。复杂度按本页参考实现计算,题库使用12个自行生成的测试点。

    • 1

    信息

    ID
    780
    时间
    1000ms
    内存
    512MiB
    难度
    普及
    标签
    递交数
    0
    已通过
    0
    上传者