链接:戳这里
3044 矩形面积求并
时间限制: 1 s
空间限制: 256000 KB
题目等级 : 钻石 Diamond
题解
题目描述 Description
输入n个矩形,求他们总共占地面积(也就是求一下面积的并)
输入描述 Input Description
可能有多组数据,读到n=0为止(不超过15组)
每组数据第一行一个数n,表示矩形个数(n<=100)
接下来n行每行4个实数x1,y1,x2,y1(0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000),表示矩形的左下角坐标和右上角坐标
输出描述 Output Description
每组数据输出一行表示答案
样例输入 Sample Input
2
10 10 20 20
15 15 25 25.5
0
样例输出 Sample Output
180.00
思路:
具体的还是看之前写的博客吧
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<iomanip>
#include<cmath>
#include<bitset>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
#define INF (1ll<<60)-1
#define Max 1e9
using namespace std;
int n;
struct Line{
double x1,x2,y;
int f;
Line(double x1=0,double x2=0,double y=0,int f=0):x1(x1),x2(x2),y(y),f(f){}
bool operator < (const Line &a)const{
if(y==a.y) return f>a.f;
return y<a.y;
}
}L[1010];
double X[1010];
int tr[4010];
double sum[4010];
void build(int root,int l,int r){
if(l==r) {
tr[root]=0;
sum[root]=0;
return ;
}
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
}
void pushup(int root,int l,int r){
if(tr[root]) sum[root]=X[r+1]-X[l];
else if(l==r) sum[root]=0;
else sum[root]=sum[root*2]+sum[root*2+1];
}
void update(int root,int l,int r,int x,int y,int v){
if(x<=l && y>=r){
tr[root]+=v;
pushup(root,l,r);
return ;
}
int mid=(l+r)/2;
if(y<=mid) update(root*2,l,mid,x,y,v);
else if(x>mid) update(root*2+1,mid+1,r,x,y,v);
else {
update(root*2,l,mid,x,mid,v);
update(root*2+1,mid+1,r,mid+1,y,v);
}
pushup(root,l,r);
}
int main(){
double x1,x2,y1,y2;
while(scanf("%d",&n)!=EOF){
if(n==0) break;
int m=0;
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
L[++m]=Line(x1,x2,y1,1);
X[m]=x1;
L[++m]=Line(x1,x2,y2,-1);
X[m]=x2;
}
sort(L+1,L+m+1);
sort(X+1,X+m+1);
int cnt=unique(X+1,X+m+1)-(X+1);
build(1,1,cnt);
int l=lower_bound(X+1,X+cnt+1,L[1].x1)-X;
int r=lower_bound(X+1,X+cnt+1,L[1].x2)-X-1;
update(1,1,cnt,l,r,L[1].f);
double ans=0;
for(int i=2;i<=m;i++){
ans+=(L[i].y-L[i-1].y)*sum[1];
l=lower_bound(X+1,X+cnt+1,L[i].x1)-X;
r=lower_bound(X+1,X+cnt+1,L[i].x2)-X-1;
if(r>=l) update(1,1,cnt,l,r,L[i].f);
}
printf("%.2f\n",ans);
}
return 0;
}