1. 程式人生 > >CF1080C Masha and two friends

CF1080C Masha and two friends

題目:Masha and two friends


思路:

首先這題思路很簡單,模擬+容斥就可以了。

即 最終的白塊數 = 原網格圖的白塊數 + 塗白增加的白塊數 - 塗黑減少的白塊數 - 又塗了白又塗了黑的那一塊減少的白塊數。

這裡重點說下怎麼求兩矩形交,我最開始就是這裡不會寫的。

下面的題解大多分類討論了,其實可以不用討論的。

如圖,要求黑色矩形和紅色居心的交。

在這裡插入圖片描述

設黑色矩形左上角座標 ( x1 , y1 ),右下角 ( x2 , y2 ) ;

紅矩形左上角座標 ( a1 , b1 ),右下角 ( a2 , b2 )。

根據重點公式,可以算出 O

1 = ( x 1 + x 2 2
, y 1 + y 2 2 )
O 2 = ( a 1 + a 2 2 , b 1 + b 2 2 ) O1 = ( \frac{ x1 + x2 }{2} , \frac{ y1 + y2 }{2} ) ,O2 = ( \frac{ a1 + a2 }{2} , \frac{ b1 + b2 }{2})

所以相交的條件就是:

a b s ( x 1 + x 2 2 a 1 + a 2 2 ) < = x 2 x 1 2 + a 2 a 1 2 abs(\frac{ x1 + x2 }{2}-\frac{ a1 + a2 }{2})<=\frac{x2-x1}{2}+\frac{a2-a1}{2}

a b s ( y 1 + y 2 2 b 1 + b 2 2 ) < = y 2 y 1 2 + b 2 b 1 2 abs(\frac{ y1 + y2 }{2}-\frac{ b1 + b2 }{2})<=\frac{y2-y1}{2}+\frac{b2-b1}{2}

整理得

a b s ( x 1 + x 2 a 1 a 2 ) < = x 2 x 1 + a 2 a 1 abs( x1 + x2 - a1 - a2)<=x2-x1+a2-a1

a b s ( y 1 + y 2 b 1 b 2 ) < = y 2 y 1 + b 2 b 1 abs( y1 + y2 - b1 - b2)<=y2-y1+b2-b1

判斷完相交,就是求相交部分的座標了。

也很好看出來,左上角是 ( m a x ( x 1 , a 1 ) , m i n ( x 2 , a 2 ) ) ( max(x1,a1) , min(x2,a2)) ,右下角是 ( m a x ( y 1 , b 1 ) , m i n ( y 2 , b 2 ) ) (max(y1,b1),min(y2,b2))


程式碼:

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

#define read(x) scanf("%d",&x)
#define ll long long

ll gets(int x,int y) {
	return ((ll)x*y+1)/2;
}

ll find(int x1,int y1,int x2,int y2) {
	x1--,y1--;
	return gets(x2,y2)+gets(x1,y1)-gets(x1,y2)-gets(x2,y1);
}

int n,m;

int main() {
	int T;
	read(T);
	while(T--) {
		read(n),read(m);
		int x1,y1,x2,y2;
		read(x1),read(y1),read(x2),read(y2);
		int a1,b1,a2,b2;
		read(a1),read(b1),read(a2),read(b2);
		
		ll ans=find(1,1,n,m);
		ans+=((ll)x2-x1+1)*(y2-y1+1)-find(x1,y1,x2,y2);
		ans-=find(a1,b1,a2,b2);
		
		if(abs(x1+x2-a1-a2)<=(x2-x1+a2-a1)&&abs(y1+y2-b1-b2)<=(y2-y1+b2-b1)) {
			ans-=((ll)min(x2,a2)-max(x1,a1)+1)*(min(y2,b2)-max(y1,b1)+1)-find(max(x1,a1),max(y1,b1),min(x2,a2),min(y2,b2));
		}
		
		printf("%I64d %I64d\n",ans,((ll)n*m)-ans);
	}
	return 0; 
}