Codeforces Round #524 (Div. 2) C. Masha and two friends

C. Masha and two friends

题目链接https://codeforc.es/contest/1080/problem/C

题意:

给出一个黑白相间的n*m的矩阵,现在先对一个子矩阵颜色变为白色,然后再对一个子矩阵颜色变为黑色,问最终白色格子和黑色格子有多少?

 

题解:

定义w(a,b)为(1,1)到(a,b)中白色的数量,通过观察找规律可以发现w(a,b)=((b+1)/2)*((a+1)/2)+(b/2)*(a/2)。

然后b(a,b)就是格子总数量减去w(a,b)。

现在对于一个子矩阵里面黑色和白色格子数量就比较容易求了。

再来分析两次变化颜色,主要时两个子矩阵交叉时,由于这里给出坐标的大小关系,所以(max(x1,x3),max(y1,y3))与(min(x2,x4),min(y2,y4))即为交叉矩阵的两个端点。

存在交叉矩阵时,黑色的数量会加上交叉矩阵中黑色的格子的数量,白色的数量会减去交叉矩阵中黑色格子的数量(结合前两次变化思考),最后直接求解即可。

 

代码如下:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll ;
int t;

ll w(ll a,ll b){
    return ((b+1)/2)*((a+1)/2)+(b/2)*(a/2);
}
ll sub_w(ll x1,ll y1,ll x2,ll y2){
    return w(x2,y2)-w(x1-1,y2)-w(x2,y1-1)+w(x1-1,y1-1);
}
ll sub_b(ll x1,ll y1,ll x2,ll y2){
    return (x2-x1+1)*(y2-y1+1)-sub_w(x1,y1,x2,y2);
}
int main(){
    scanf("%d",&t);
    while(t--){
        ll n,m,x1,x2,x3,x4,y1,y2,y3,y4;
        cin>>n>>m>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
        ll sub_x1 = max(x1,x3),sub_y1=max(y1,y3),sub_x2=min(x2,x4),sub_y2=min(y2,y4);
        ll num_w = w(n,m),num_b = n*m - num_w;
        num_w+=sub_b(x1,y1,x2,y2);num_b-=sub_b(x1,y1,x2,y2);
        num_b+=sub_w(x3,y3,x4,y4);num_w-=sub_w(x3,y3,x4,y4);
        if(sub_x1<=sub_x2 && sub_y1<=sub_y2){
            num_b+=sub_b(sub_x1,sub_y1,sub_x2,sub_y2);
            num_w-=sub_b(sub_x1,sub_y1,sub_x2,sub_y2);
        }
        cout<<num_w<<" "<<num_b<<endl;
    }
    return 0;
}

 

posted @ 2018-11-25 20:51  heyuhhh  阅读(164)  评论(0编辑  收藏  举报