题意:求矩形并区域面积的总和。
利用线段树来解决这个问题,首先将这个矩形投影到x轴(y轴也可),同时记录矩形的高度,利用线段树找到相邻的两个x点,即矩形的长,然后再乘以矩形的高,即可得到矩形的一部分面积,再将这些面积加在一起,就可以得到矩形的面积。
~纪念思考了一天多的题目~
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAX 2005
struct lnode
{
double l,r,h;
int d;
}line[MAX*2];
struct node
{
int l,r,flag;
double sum;
}tree[4*MAX];
double X[MAX*4];
int k;
void build(int pos,int l,int r)
{
tree[pos].l=l;
tree[pos].r=r;
tree[pos].flag=0;
tree[pos].sum=0;
if(l==r-1)
return;
int mid=(l+r)>>1;
build(2*pos,l,mid);
build(2*pos+1,mid,r);
}
int cmp(lnode a,lnode b)
{
return a.h<b.h;
}
int Search(double x)
{
int mid,low=0,high=k;
while(low<=high)
{
mid=(low+high)/2;
if(X[mid]==x)
{
return mid;
}
else if(X[mid]<x)
{
low=mid+1;
}
else
{
high=mid-1;
}
}
return -1;
}
void update(int step,int l,int r,int c)
{
if(l<=tree[step].l&&tree[step].r<=r)
{
tree[step].flag+=c;
if(tree[step].flag!=0)//说明该区域被覆盖
tree[step].sum=X[tree[step].r]-X[tree[step].l];
else
tree[step].sum=tree[step*2].sum+tree[step*2+1].sum;
return;6
}
int mid=(tree[step].l+tree[step].r)>>1;
if(mid<r)//这段代码的作用是求得任意相邻的x1,x2之间的距离
{
update(step*2+1,l,r,c);
}
if(l<mid)
{
update(step*2,l,r,c);
}
if(tree[step].flag!=0)//回溯
tree[step].sum=X[tree[step].r]-X[tree[step].l];
else
tree[step].sum=tree[step*2].sum+tree[step*2+1].sum;
}
int main()
{
int n,i,t=0,m;
double a,b,c,d,sum;
while(scanf("%d",&n)&&n)
{
m=0;
while(n--)
{
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
X[m]=a;
line[m].l=a;
line[m].r=c;
line[m].h=b;
line[m].d=1;
m++;
X[m]=c;
line[m].l=a;
line[m].r=c;
line[m].h=d;
line[m].d=-1;
m++;
}
sort(X,X+m);
sort(line,line+m,cmp);
k=0;
for(i=1;i<=m;i++)
if(X[i]!=X[i-1])
X[k++]=X[i-1];
k--;
build(1,0,k);
sum=0;
for(i=0;i<m;i++)
{
int l,r;
l=Search(line[i].l);//找到离散化之后的端点坐标
r=Search(line[i].r);
update(1,l,r,line[i].d);
sum+=tree[1].sum*(line[i+1].h-line[i].h);
}
printf("Test case #%d\n",++t);
printf("Total explored area: %.2lf\n\n",sum);
}
return 0;
}