题目描述
Farmer John has purchased a new machine that is capable of planting grass within any rectangular region of his farm that is "axially aligned" (i.e., with vertical and horizontal sides). Unfortunately, the machine malfunctions one day and plants grass in not one, but N (1 <= N <= 1000) different rectangular regions, some of which may even overlap.
Given the rectangular regions planted with grass, please help FJ compute the total area in his farm that is now covered with grass.
在一个笛卡尔平面坐标系里(则X轴向右是正方向,Y轴向上是正方向),有N(1<=N<=10001<=N<=1000)个矩形,第i个矩形的左上角坐标是(x1, y1),右下角坐标是(x2,y2)。问这N个矩形所覆盖的面积是多少?注意:被重复覆盖的区域的面积只算一次。
输入格式
第一行,一个整数N。 (1<=N<=10001<=N<=1000)。
接下来有N行,每行描述一个矩形的信息,分别是矩形的x1、y1、x2、y2。
其中 -10^8<=x1,y1,x2,y2<=10^8−108<=x1,y1,x2,y2<=108。
输出格式
一个整数,被N个矩形覆盖的区域的面积。
输入输出样例
输入 #1复制
2 0 5 4 1 2 4 6 2
输出 #1复制
20
上代码:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=1005;
struct node{ll x1,y1,x2,y2;}a[maxn];
int n,tot=0;
void Add(ll x1,ll y1,ll x2,ll y2){a[++tot]=(node){x1,y1,x2,y2};}
void Cut(int p,ll x1,ll y1,ll x2,ll y2,int cmd){
ll k1,k2;
if(!cmd){
k1=max(x1,a[p].x1);
k2=min(x2,a[p].x2);
if(a[p].x1<k1)Add(a[p].x1,a[p].y1,k1,a[p].y2);
if(k2<a[p].x2)Add(k2,a[p].y1,a[p].x2,a[p].y2);
Cut(p,k1,y1,k2,y2,1);
}
else{
k1=min(y1,a[p].y1);
k2=max(y2,a[p].y2);
if(a[p].y1>k1)Add(x1,a[p].y1,x2,k1);
if(k2>a[p].y2)Add(x1,k2,x2,a[p].y2);
}
}
int main(){
scanf("%d",&n);
ll x1,y1,x2,y2;
scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
Add(x1,y1,x2,y2);//先加入一个矩形
for(int i=2;i<=n;i++){
scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
for(int j=1;j<=tot;j++){
if(a[j].x1>=x2||a[j].x2<=x1||a[j].y1<=y2||a[j].y2>=y1)continue;//判断是否相交
Cut(j,x1,y1,x2,y2,0);//若相交,则用当前矩形去切割
a[j]=a[tot];//删除原矩形,用最后一个矩形来覆盖它
tot--;j--;
}
Add(x1,y1,x2,y2);//加入新矩形
}
ll ans=0;
for(int i=1;i<=tot;i++)ans+=(a[i].x2-a[i].x1)*(a[i].y1-a[i].y2);//计算面积并
printf("%lld\n",ans);
return 0;
}