Codeforces Round #524 (Div. 2) C. Masha and two friends (思维分析)

题目链接

题意

Codeforces Round #524 (Div. 2) C. Masha and two friends (思维分析)_第1张图片
如图所示,给一个n*m的黑白棋盘,列代表x,行代表y,分别给出两个矩形rec1,rec2的左下角和右上角坐标,rec1会把其覆盖的区域全部变成白色,rec2会把其覆盖的区域全部变成黑色。
rec1先,rec2后。
问最终棋盘有多少个白色格子和多少个黑色格子。

题解

①首先考虑初始给出n*m的棋盘中有多少个白格子和黑格子

  1. 对于面积是偶数的棋盘,黑白格子对半分
  2. 对于面积是奇数的棋盘,观察(1,1)格子颜色,如果是白色,则白色比黑色多1,否则黑色比白色多1。

②之后分开考虑一个矩形覆盖的情况

  1. 如果是白色矩形覆盖,那么可以用①的信息,计算出里面有多少个黑格子,就知道多了多少个白格子了。
  2. 左下角的坐标可以判断这个方块左下角是黑格子还是白格子,如果x+y是奇数则黑,反之白。

③考虑两个矩形重合
rec1: (x1,y1,x3,y3) rec2: (x2,y2,x4,y4)

  1. 重合矩形的左下角坐标为 max(x1,x3), max(y1,y3),右上角坐标为min(x2,x4), min(y2,y4)。
  2. 重合的情况便是,之前白色区域覆盖的黑色格子需要全部还回去,所以只需要算出重合区域初始有多少个黑格子即可 。

代码

#include 
using namespace std;


typedef long long ll;
typedef pair<ll,ll> pll; // 1 黑 2白
const int maxn = 1e5+5;
pll fw(long long x, long long y) {
	long long b = x*y/2;
	long long w = x*y-b;
    return pll(b,w);
}
pll fb(long long x, long long y) {
	long long w = x*y/2;
	long long b = x*y-w;
    return pll(b,w);    
}
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        long long x,y; // m n
        scanf("%lld%lld", &y, &x);
        long long x1,x2,x3,x4,y1,y2,y3,y4;
        scanf("%lld%lld%lld%lld", &x1,&y1, &x2, &y2); // 白
        scanf("%lld%lld%lld%lld", &x3,&y3, &x4, &y4); // 黑
        pll p = fw(x,y);
        long long sb = p.first;
        long long sw = p.second;
        // cout <<"初始:" << sw <<" " << sb << endl;
        long long c1 = x2-x1+1;
        long long r1 = y2-y1+1;
        long long c2 = x4-x3+1;
        long long r2 = y4-y3+1;
        
        long long dx = min(x2,x4)-max(x1,x3)+1;
        long long dy = min(y2,y4)-max(y1,y3)+1;
        long long _x3 = max(x1,x3);
        long long _y3 = max(y1,y3);
        if((x1+y1)%2 == 0) {
            p = fw(c1,r1);
        }
        else {
            p = fb(c1,r1);
        }
        sw += p.first; // 黑
        sb -= p.first;

        pll p2(0,0);
        if((x3+y3)%2 == 0) {
            p = fw(c2,r2);
            
        }
        else 
            p = fb(c2,r2);
        sb += p.second; // 白
        sw -= p.second;

        if(dx > 0 && dy > 0) {
            if((_x3+_y3)%2 == 0){
                p2 = fw(dx,dy);
            }
            else 
                p2 = fb(dx,dy);
        }

        sw -= p2.first;
        sb += p2.first;
        cout << sw <<" " << sb << endl;
    }
    return 0;
}


你可能感兴趣的:(思维)