• Codeforces Round #524 (Div. 2) Masha and two friends矩形


    题目

    题意

         给一个n*m块大的黑白相间的矩形,在这个举行中操作,要先把第一个矩形(左下角坐标(x1,y2),右上角坐标(x2,y2)) 全部涂成白色,再把第二个矩形(左下角坐标(x3,y3),右上角坐标(x4,y4))  全部涂成黑色。 求涂了这两个矩形之后的 白色块数量和黑色块数量。

    思路

        上图。因为在第二步中全涂成黑色,可能会  覆盖第一个矩形的一部分。如果先求白色块,然后通过n*m-白色再求出黑色的方法,不太好求。所以先求黑色块数量,再通过n*m-黑色 求白色。

        答案黑色块的数量设为numblack ( 即nb ),nb = n*m中总的黑色数量  - s1中的黑色数量 - s2中的黑色数量 - s3中的黑色数量 + (s2+s3)的面积,    等价于nb = n*m中总的黑色数量  - (s1+s2)中的黑色数量 -  (s2+s3)中的黑色数量 + s2中的黑色数量 + (s2+s3)的面积。这样比较好求。

        而求一个矩形中黑色方块的数量,容易知道不是 白==黑 ,就是 白与黑相差为1(其中矩形左下角是黑色的话,黑色的数量就会比白色多1,这也是必要条件)   

         xx1=max(x[1],x[3]);
         xx2=min(x[2],x[4]);
         yy1=max(y[1],y[3]);
         yy2=min(y[2],y[4]);  如果  xx1<=xx2 && yy1<=yy2 ,则有重叠面积,s2部分存在。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include <cctype>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<string>
     8 #include<cmath>
     9 #include<set>
    10 #include<vector>
    11 #include<stack>
    12 #include<queue>
    13 #include<map>
    14 using namespace std;
    15 #define ll long long
    16 #define mem(a,x) memset(a,x,sizeof(a))
    17 #define se second
    18 #define fi first
    19 const ll mod=1000000007;
    20 const int INF= 0x3f3f3f3f;
    21 const int inf= 1000002;
    22 const int N=1e5+5;
    23 
    24 int t,n,m;
    25 ll x[5],y[5];
    26 ll nb; 
    27 
    28 ll numblack(ll x1,ll y1,ll x2,ll y2)
    29 {
    30     // 矩形里 黑色数量要+1的唯一情况: 
    31     if((x2-x1+1)%2==1  &&  (y2-y1+1)%2==1 && (x1+y1)%2==1)
    32         return (x2-x1+1)*(y2-y1+1)/2 +1;
    33     else
    34         return (x2-x1+1)*(y2-y1+1)/2 ;
    35 }
    36 
    37 int main()
    38 {
    39     cin>>t;
    40     while(t--)
    41     {
    42         scanf("%d%d",&n,&m);
    43         for(int i=1;i<=4;i++)
    44             scanf("%d%d",&x[i],&y[i]);
    45         
    46         nb = numblack(1,1,m,n);
    47         nb-= numblack( x[1],y[1],x[2],y[2] );
    48         nb-= numblack( x[3],y[3],x[4],y[4] );
    49         
    50         ll xx1=max(x[1],x[3]);
    51         ll xx2=min(x[2],x[4]);
    52         ll yy1=max(y[1],y[3]);
    53         ll yy2=min(y[2],y[4]);
    54         if(xx1<=xx2 && yy1<=yy2) //如果重叠 加上重合部分(容斥定理) 
    55             nb+= numblack( xx1,yy1,xx2,yy2 );
    56         
    57         nb+= (x[4]-x[3]+1)*(y[4]-y[3]+1);
    58         cout<<1LL*n*m-nb<<' '<<nb<<endl;
    59     }    
    60 }
    View Code
  • 相关阅读:
    【C#】Send data between applications
    【C#】Switch datatype between object and byte[]
    【C#】Get the html code of a webpage
    MSIL Hello World
    MonoGame 3.2 下,截屏与 Texture2D 的保存
    mciSendString 的两个小坑
    virtual 修饰符与继承对析构函数的影响(C++)
    让 OpenAL 也支持 S16 Planar(辅以 FFmpeg)
    博客园第一篇——SDL2+FFmpeg 制作简单播放器&同步
    第五次UML作业——结对作业二:班级成绩表
  • 原文地址:https://www.cnblogs.com/thunder-110/p/10050961.html
Copyright © 2020-2023  润新知