• Artwork 18年中南多校第一场A


    一、题意

    对于一个矩阵,若干道命令,每道命令将会把某一段格子涂黑,请问每次涂黑之后矩阵中未被涂黑的块的数量?

    二、思路

    保存每道命令,并且忠实的执行他,到最后一步开始搜索联通块的数量,并将其保存。

    之后对于每道命令做撤回操作。每次撤回之后重新扫描命令覆盖区域中已经是空白块的区域。并且将它们用并查集的方式统一起来。

    最后倒序输出保存的答案。

    三、代码实现

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<vector>
    #include<math.h>
    #include<string.h>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<string>
    #include<queue>
    
    using namespace std;
    #define ll long long 
    #define veci vector<int>
    #define pp pair<ll,ll>
    #define vecp vector<pp>
    
    const ll MAXN=1233;
    
    class point
    {
        public :
            int x;int y;
            point(){}
            point(int a,int b):x(a),y(b){}
            bool const operator == (point const &p1)
            {
                return x==p1.x&&y==p1.y;
            }
    };
    
    class order
    {
        public :
            point from,to;
            order(){}
            order(int a,int b,int c,int d)
            {
                from = point(a,b);
                to = point(c,d);
            }
    };
    ll n,m,k,num;
    vector<order>ord;
    veci ans;
    point sett[MAXN][MAXN];
    int mapp[MAXN][MAXN];
    int addx[]={0,0,1,-1};
    int addy[]={1,-1,0,0};
    
    void draw(order o1)
    {
        for(int i=o1.from.x;i<=o1.to.x;++i)
        {
            for(int j=o1.from.y;j<=o1.to.y;++j)
            {
                if(mapp[i][j]==-1)mapp[i][j]=0;
                mapp[i][j]++;    
            }        
        }
    }
    void erase(order o1)
    {
        for(int i=o1.from.x;i<=o1.to.x;++i)
        {
            for(int j=o1.from.y;j<=o1.to.y;++j)
            {
                mapp[i][j]--;    
            }        
        }
    
    }
    
    
    const point ZERO(0,0);
    
    void dfs(int x,int y,point tar)
    {
        if(x<1||x>n||y<1||y>m||mapp[x][y]!=-1||sett[x][y]==tar)return ;        
        sett[x][y]=tar;
        mapp[x][y]=0;
        for(int i=0;i<4;++i)
        {
            dfs(x+addx[i],y+addy[i],tar);    
        }
    }    
    
    point find_set(int x,int y)
    {
        if(sett[x][y].x==x&&sett[x][y].y==y)return sett[x][y];
        else return sett[x][y]=find_set(sett[x][y].x,sett[x][y].y);
    }
    
    void show(point p1)
    {
        int x=p1.x;
        int y=p1.y;
        cout<<"x: "<<x<<" y: "<<y<<endl;
    }
    
    void deal(order o1)
    {
        for(int i=o1.from.x;i<=o1.to.x;++i)
            for(int j=o1.from.y;j<=o1.to.y;++j)
            {
                if(mapp[i][j]==0)
                {
                    int isDealed=0;
                    for(int k=0;k<4;++k)
                    {
                        int x=i+addx[k];
                        int y=j+addy[k];
                        if(x<1||y<1||x>n||y>m)continue;
                        if(mapp[x][y]==0)
                        {
                            if(sett[x][y]==ZERO)continue;
                            if(!isDealed)
                            {            
                                sett[i][j]=sett[x][y]=find_set(x,y);    
                                                                                
                            }else
                            {
                                
                                sett[x][y]=find_set(x,y);
                                sett[i][j]=find_set(i,j);
                                if(sett[i][j]==sett[x][y])continue;                    
                                int xx=sett[x][y].x;
                                int yy=sett[x][y].y;
                                sett[xx][yy]=sett[i][j];
                                num--;
                            }
                            isDealed++;
                        }
                    }if(!isDealed)
                    {
                        sett[i][j]=point(i,j);
                        num++;    
                    }
                    
                }
            }
                    
    }
    
    void init()
    {
        num=0;
        ord.clear();
        ans.clear();
        memset(mapp,-1,sizeof(mapp));
        memset(sett,0,sizeof(sett));
        for(int i=0;i<k;++i)
        {
            int a,b,c,d;
            cin>>a>>b>>c>>d;
            order o1(a,b,c,d);
            draw(o1);
            ord.push_back(o1);
        }    
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
            {
                if(mapp[i][j]==-1)
                {
                    point tar(i,j);
                    dfs(i,j,tar);
                    num++;    
                }
            }
        ans.push_back(num);
        
        int len=ord.size();
        for(int i=len-1;i;--i)
        {
                order now=ord[i];
                erase(now);
                deal(now);
                ans.push_back(num);
        }
        len = ans.size();
        for(int i=len-1;i>=0;--i)
            cout<<ans[i]<<endl;
        
            
    
    }
    
    
    int main()
    {
    //    cin.sync_with_stdio(false);    
        
        while(cin>>n>>m>>k)init();
    
        return 0;
    }
  • 相关阅读:
    URL中#号(井号)的作用
    Sublime Text2 快捷键汇总
    Sublime Text2 使用及插件配置
    Sumblime Text 2 常用插件以及安装方法
    CSS禁止选择文本功能(兼容IE,火狐等浏览器)
    JavaScript 判断 URL
    纯真IP数据库格式读取方法(JAVA/PHP/Python)
    Sublime Text 2 性感无比的代码编辑器!程序员必备神器!跨平台支持Win/Mac/Linux
    base64:URL背景图片与web页面性能优化
    数独DFS实现
  • 原文地址:https://www.cnblogs.com/rikka/p/8694190.html
Copyright © 2020-2023  润新知