求矩形面积并。。扫描线第一题。把x坐标离散化,y坐标排序,从低到高一条一条线段处理,每次得到前一段面积。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <stack>
using namespace std;
int n;
struct Seg{
double xl,xr;
double y;
int flag;
Seg(){
}
Seg(double xl,double xr,double y,int flag):xl(xl),xr(xr),y(y),flag(flag){}
bool operator<(const Seg& other)const{
return y<other.y;
}
};
double X[210];
Seg seg[210];
const double eps = 1e-8;
bool equal(double a,double b){
if(fabs(a-b)<eps)return 1;
return 0;
}
int bs(double d,int L,int R){
while(L<=R){
int mid = (L+R)>>1;
if(equal(X[mid],d))return mid;
if(X[mid]<d){
L=mid+1;
}else{
R=mid-1;
}
}
return -1;
}
struct node{
int l,r;
int cnt;
double width;
}tree[810];
void build_tree(int n,int l,int r){
tree[n].l=l; tree[n].r=r;
tree[n].cnt=0; tree[n].width=0.0;
if(l==r)return;
int mid=(l+r)>>1;
build_tree(n<<1,l,mid);
build_tree((n<<1)|1,mid+1,r);
}
void push_up(int n){
if(tree[n].cnt){
tree[n].width=X[tree[n].r+1]-X[tree[n].l];
}else{
tree[n].width=0;
}
if(tree[n].l<tree[n].r)tree[n].width=max(tree[n<<1].width+tree[(n<<1)|1].width,tree[n].width);
}
void update(int n,int l,int r,int val){
if(tree[n].l==l&&tree[n].r==r){
tree[n].cnt+=val;
push_up(n);
return;
}
int mid = (tree[n].l+tree[n].r)>>1;
if(mid>=r){
update(n<<1,l,r,val);
}else{
if(mid<l){
update((n<<1)|1,l,r,val);
}else{
update(n<<1,l,mid,val);
update((n<<1)|1,mid+1,r,val);
}
}
push_up(n);
}
int main(){
int cas=0;
while(cin>>n){
cas++;
if(!n)break;
int m=0;
for(int i=0;i<n;i++){
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
X[m]=x1;
seg[m++]=Seg(x1,x2,y1,1);
X[m]=x2;
seg[m++]=Seg(x1,x2,y2,-1);
}
sort(X,X+m);
sort(seg,seg+m);
int k = unique(X,X+m)-X;
double re=0.0;
build_tree(1,0,k-1);
for(int i=0;i<m;i++){
double curWidth = tree[1].width;
if(i){
re+=curWidth*(seg[i].y-seg[i-1].y);
}
int l = bs(seg[i].xl,0,k-1);
int r = bs(seg[i].xr,0,k-1);
update(1,l,r-1,seg[i].flag);
}
printf("Test case #%d\n",cas);
printf("Total explored area: %.2f\n\n",re);
}
return 0;
}