hdu 1542 線段樹之掃描線之面積並


點擊打開鏈接

題意:給你n個矩形,求它們的面積,重復的不重復計算

思路:用線段樹的掃描線完成,將X坐標離散化后,從下到上掃描矩形,進行各種處理,看代碼注釋把

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e3+10;
#define mm(a) memset(a,0,sizeof(a))
int num1[maxn*4];
double num[maxn*4],X[maxn*4];
struct edge{
double l,r,h;
int s;//s為1是下邊,s為-1是上邊
edge(){};
edge(double a,double b,double c,int d) : l(a),r(b),h(c),s(d){}
bool operator<(const edge &n)const{
return h<n.h;
}
}ss[maxn];
void pushup(int le,int ri,int node){
if(num1[node]) num[node]=X[ri+1]-X[le];//在更新的時候,可能兩個矩陣有重疊,這樣就不能像以前那么更新,而是將le和ri傳入
else if(le==ri) num[node]=0; //然后將X[ri+1]-X[le]的值進行更新,避免了重復的長度
else num[node]=num[node<<1]+num[node<<1|1];
}
void update(int l,int r,int add,int le,int ri,int node){
if(l<=le&&ri<=r){
num1[node]+=add;//與懶惰標記類似
pushup(le,ri,node);
return ;
}
int t=(le+ri)>>1;
if(l<=t) update(l,r,add,le,t,node<<1);
if(r>t) update(l,r,add,t+1,ri,node<<1|1);
pushup(le,ri,node);
}
int main(){
int n,t=1;
while(scanf("%d",&n)!=-1){
if(n==0) break;
double a,b,c,d;
int k=0;
for(int i=0;i<n;i++){
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
X[k]=a;
ss[k++]=edge(a,c,b,1);
X[k]=c;
ss[k++]=edge(a,c,d,-1);
}
sort(X,X+k);
sort(ss,ss+k);
int k1=1;
for(int i=1;i<k;i++){//對X進行離散化
if(X[i]!=X[i-1]) X[k1++]=X[i];
}
mm(num);mm(num1);
double ans=0;
for(int i=0;i<k-1;i++){
int l=lower_bound(X,X+k1,ss[i].l)-X;
int r=lower_bound(X,X+k1,ss[i].r)-X-1;
update(l,r,ss[i].s,0,k1-1,1);
ans+=num[1]*(ss[i+1].h-ss[i].h);//num[1]為當前橫坐標的總長度
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",t++,ans);
}
return 0;
}


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com