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; }