1. 程式人生 > >Codeforces Round #524-C-Masha and two friends

Codeforces Round #524-C-Masha and two friends

 

題目連結

 

 

 

 

看了半天程式碼才看出怎麼做的,然後寫了註釋

首先白色和黑色不一定相等,這裡寫了一個求x1y1->x2y2中白色有多少的函式(求黑色用總的減去白色即可)

首先一開始白色有Getwhite-1,1->n,m個,

然後澆上白色的漆,那麼x1y1->x2y2中的黑色變成白色,

也就是white += Getblack-x1y1->x2y2

再然後澆上黑色的漆,

如果兩次的矩陣沒有交叉的話,減去第二個矩陣中的白色(被黑色漆澆上自然不是白色的了)

white-=Getwhite-x3y3->x4y4

如果有交叉的話,再減掉交叉矩陣中的黑色,

(因為那一片中,是白色--->黑色,而上面算的是黑白->黑,自然是少考慮了黑色的)

white -= Getblack-x5y5->x6y6

這樣白色的就算出來了,黑色用總數減掉白色就好

求矩陣的交叉部分的矩陣和求白色塊的多少是個難點(對於我來說,然而看到程式碼之後就很簡單了)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t,n,m,x1,x2,x3,x4,y1,y2,y3,y4,x5,x6,y5,y6;
ll white,black;
ll Getwhite(int x1,int y1,int x2,int y2){
    int c = (x1+y1)%2==0;
    if((x2-x1+1)%2==0||(y2-y1+1)%2==0)c = 0;
    return 1ll*(x2-x1+1)*(y2-y1+1)/2+c;
}
ll Getblack(int x1,int y1,int x2,int y2){
    return 1ll*(x2-x1+1)*(y2-y1+1) - Getwhite(x1,y1,x2,y2);
}
int main()
{
    cin>>t;
    while(t--){
        cin>>n>>m;
        cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
        white = Getwhite(1,1,n,m);///at the start
        white += Getblack(x1,y1,x2,y2);///get the white (subtract the black)
        white -= Getwhite(x3,y3,x4,y4);///get the black
        x5 = max(x1,x3),x6 = min(x2,x4);
        y5 = max(y1,y3),y6 = min(y2,y4);
        if(x5<=x6 && y5<=y6)///if exist cross
            white -= Getblack(x5,y5,x6,y6);///subtract the black
        black = 1ll*n*m - white;
        cout<<white<<" "<<black<<endl;
    }
    return 0;
}