• SGU 177 Square


    题意:给出一个n×n的矩阵,矩阵上每个格子最开始都是白色的,给出m个操作,每个操作会把一个矩形染成黑色或白色,问最后有多少个白的格子。

    思路:这题让我不禁想起了poj 2528,这类的染色问题应该都能用并查集搞……从后往前处理操作,这样已经画过的地方就不会第二次被染色,然后把染过的标记一下,接下来就是用并查集把染过的“跳过去”就好了,在这个过程中统计一下染过的黑色格子的数量,用总量一减就OK了~不过按这题的数据量来看,线段树应该也是完全没问题的……
    ————————————————
    版权声明:本文为CSDN博主「qian99」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qian99/article/details/17171575

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<cmath>
    #include<vector>
    #define inf 0x3f3f3f3f
    #define Inf 0x3FFFFFFFFFFFFFFFLL
    #define eps 1e-9
    #define pi acos(-1.0)
    using namespace std;
    typedef long long ll;
    const int maxn=1000+10;
    int parents[maxn][maxn];
    bool vis[maxn][maxn];
    int Find(int r,int x)
    {
        return parents[r][x]==x?x:parents[r][x]=Find(r,parents[r][x]);
    }
    struct Paint
    {
        int x1,y1,x2,y2;
        int colors;
        void readit()
        {
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        }
        void change()
        {
            if(x1>x2) swap(x1,x2);
            if(y1>y2) swap(y1,y2);
        }
    }paints[maxn*5];
    int main()
    {
     
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int n,m;
        scanf("%d%d",&n,&m);
        char str[5];
        for(int i=0;i<m;++i)
        {
            paints[i].readit();
            paints[i].change();
            scanf("%s",str);
            if(str[0]=='b') paints[i].colors=1;
            else paints[i].colors=0;
        }
        for(int i=1;i<=n;++i)
          for(int j=1;j<=n;++j)
             parents[i][j]=j;
        memset(vis,0,sizeof(vis));
        int total=n*n;
        int now,f;
        for(int i=m-1;i>=0;--i)
        {
            for(int j=paints[i].x1;j<=paints[i].x2;++j)
            {
                now=paints[i].y1;
                while(now<=paints[i].y2)
                {
                    f=Find(j,now);
                    if(f==now&&!vis[j][now])
                    {
                        vis[j][now]=true;
                        parents[j][now]=paints[i].y2;
                        if(paints[i].colors) total--;
                        now++;
     
                    }
                    else now=f+1;
                }
            }
        }
        printf("%d
    ",total);
        return 0;
    }
    

      Sol2:

    倒着扫描每个矩形,处理每个矩形时,向后遍历判断后面的矩形是否与其重叠,重叠的话就分割冲若干种小的矩形继续处理,直到最后统计没有被覆盖的面积..实现直接看代码吧..

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    using namespace std;
    typedef long long ll;
    int n,m;
    int x1[10020],x2[10020],y1[10020],y2[10020];
    int col[10020];
    char c[3];
    int cnt;
    void slove(int xs,int ys,int xt,int yt,int d,int c)
    {
    
        while (((xs>=x2[d])||(xt<=x1[d])||(ys>=y2[d])||(yt<=y1[d]))&& d<=m)
        //如果左上角点所在行>=第D个矩形右下角,即在第D个矩形下方 
    	// 右下角行<=第D个矩形左上角,即在其上方,后面两个同理 
    	      d++;
        if (d==m+1)
        {
            if (c) 
    		   cnt+=(yt-ys)*(xt-xs);
    		    //出现了多少个黑色点 
            return;
        }
        if (xs<x1[d])
        {
            slove(xs,ys,x1[d],yt,d+1,c);
            xs=x1[d];
        }
        if (xt>x2[d])
        {
            slove(x2[d],ys,xt,yt,d+1,c);
            xt=x2[d];
        }
        if (ys<y1[d]) 
    	    slove(xs,ys,xt,y1[d],d+1,c);
        if (yt>y2[d])
    	     slove(xs,y2[d],xt,yt,d+1,c);
    }
    int main()
    {
    //    freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&m);
        cnt=0;
        
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]);
            if (x1[i]>x2[i]) swap(x1[i],x2[i]);
            if (y1[i]>y2[i]) swap(y1[i],y2[i]);
            x2[i]++;
            y2[i]++;
            scanf("%s",c);
            if (c[0]=='b')
    		   col[i]=1;
            else 
    		    col[i]=0;
        }
        for (int i=m; i>=1; i--)
        {
            if (col[i])
            slove(x1[i],y1[i],x2[i],y2[i],i+1,1);
        }
        cout<<n*n-cnt<<endl;
    
        return 0;
    }
    

      

  • 相关阅读:
    【python cookbook】【数据结构与算法】4.找到最大或最小的N个元素
    【python cookbook】【数据结构与算法】3.保存最后N个元素
    oracle sql语言模糊查询--通配符like的使用教程
    oracle decode处理被除数为0 的情况
    握草
    oracle if else 判断
    Procdure for wanfo business report
    [转]Oracle 阳历转农历
    阴阳历互相转换方法
    [转]解决crystal report水晶报表在浏览器提示bobj未定义的错误
  • 原文地址:https://www.cnblogs.com/cutemush/p/14600691.html
Copyright © 2020-2023  润新知