• 计蒜客 A.Artwork 并查集+set


    链接:点击打开链接

    题意:画直线分区域,问每画完一条线有几个区域

    思路:倒着做变成擦直线,合并区域或形成新区域。可以使用并查集来维护。启发:类似拆分的问题都可以倒过来离线变成合并的问题。

    代码:

    #include<bits/stdc++.h>
    #define LL long long
    #define PB push_back
    #define pii pair<int,int>
    #define MP make_pair
    #define X first
    #define Y second
    using  namespace std;
    typedef long long ll;
    const int maxn=2e6+10;
    pii f[10004],s[10004];
    int mp[1005][1005];
    int fa[maxn];
    set<int> ST;
    int fin(int x){
        if(fa[x]==x)return x;
        fa[x]=fin(fa[x]);
        return fa[x];
    }
    
    void combin(int x,int y){
        int fx=fin(x),fy=fin(y);
        if(fx!=fy){
            fa[fx]=fy;
            if(ST.find(fx)!=ST.end()){
                ST.erase(ST.find(fx));
            }
            ST.insert(fy);
        }
        return;
    }
    
    int hs(int x,int y){
        return x*1000+y-1;
    }
    
    void up(int xx,int yy){
        ST.insert(hs(xx,yy));
        if(mp[xx+1][yy]==0) combin(hs(xx,yy),hs(xx+1,yy));
        if(mp[xx-1][yy]==0) combin(hs(xx,yy),hs(xx-1,yy));
        if(mp[xx][yy+1]==0) combin(hs(xx,yy),hs(xx,yy+1));
        if(mp[xx][yy-1]==0) combin(hs(xx,yy),hs(xx,yy-1));
        if(fin(hs(xx,yy))!=hs(xx,yy)&&ST.find(hs(xx,yy))!=ST.end()) ST.erase(ST.find(hs(xx,yy)));
    }
    
    int main(){
        int n,m,q;
        scanf("%d%d%d",&n,&m,&q);
        for(int i=0;i<maxn;i++) fa[i]=i;
        for(int i=0;i<q;i++){
            scanf("%d%d%d%d",&f[i].X,&f[i].Y,&s[i].X,&s[i].Y);
            if(f[i].X==s[i].X){
                if(f[i].Y>s[i].Y) swap(s[i],f[i]);
                for(int j=f[i].Y;j<=s[i].Y;j++) ++mp[f[i].X][j];
            }
            else{
                if(f[i].X>s[i].X) swap(s[i],f[i]);
                for(int j=f[i].X;j<=s[i].X;j++) ++mp[j][f[i].Y];
            }
        }
        for(int i=0;i<=n+1;i++) mp[i][m+1]=mp[i][0]=1;
        for(int i=0;i<=m+1;i++) mp[n+1][i]=mp[0][i]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(mp[i][j]==0)up(i,j);
        vector<int> ans;
        for(int i=q-1;i>=0;i--){
            ans.PB(ST.size());
            if(f[i].X==s[i].X){
                if(f[i].Y>s[i].Y) swap(s[i],f[i]);
                for(int j=f[i].Y;j<=s[i].Y;j++){
                    --mp[f[i].X][j];
                    if(mp[f[i].X][j]==0) up(f[i].X,j);
                }
            }
            else{
                if(f[i].X>s[i].X) swap(s[i],f[i]);
                for(int j=f[i].X;j<=s[i].X;j++){
                    --mp[j][f[i].Y];
                    if(mp[j][f[i].Y]==0)up(j,f[i].Y);
                }
            }
        }
        reverse(ans.begin(),ans.end());
        for(int a:ans) printf("%d
    ",a);
        return 0;
    }


  • 相关阅读:
    使用japidocs生成springboot api文档
    springboot通过javaconfig配置jackson
    SAP 合并请求
    windows server终端服务加密级别
    Microsoft Windows远程桌面协议服务程序密钥泄露漏洞(CVE-2005-1794)
    SAP RFC函数RFC_READ_TABLE使用与优化
    springboot maven项目引入并打包本地JAR
    springboot通过javaconfig实现logback配置
    File类以及文件简记
    解释性语言和编译型语言简记
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672479.html
Copyright © 2020-2023  润新知