本人太菜,注释写得有点多,都是自己错了的地方~~~以后一定好好记住
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define lson l , m , th << 1
#define rson m + 1 , r , th << 1 | 1
#define MAX 500
using namespace std;
//题目核心思想是把一个正方形看成两条边,再以每条边的高度进行排序,然后再一次往上扫描。
//所以这一类题目又叫线段扫描
struct line{
double l,r,h;
int flag;//如果flag=1,则为上边;如果flag=-1,则为下边
line (){}
line(double a,double b,double c,int d) : l(a) , r(b) , h(c) , flag(d) {}
bool operator < (const line &cmp) const {
return h < cmp.h;
}
}ll[MAX];
int cover[MAX*4];
double sum[MAX*4];
double X[MAX];//用于离散化,通过Bin()这个函数实现离散化
int Bin(double key,int n,double X[]){
int l=0,r=n-1;
while(l<=r){
int m=(l+r)/2;
if(X[m]<key) l=m+1;
if(X[m]>key) r=m-1;//这儿的-1很重要,记住!
if(X[m]==key) return m;
}
return -1;
}
void PushUp(int th,int l,int r){
//if(l==r) sum[th]=0;
//else if(cover[th]) sum[th]=X[r+1]-X[l];
//理解线段树的性质,写成这样可以说完全没懂什么叫线段树!!
//printf("l:%d r:%d %d th:%d\n",l,r,cover[th],th);
if(cover[th]) sum[th]=X[r+1]-X[l];
else if(l==r) sum[th]=0;//经常都需要特判叶子节点,因为它很特殊
else sum[th]=sum[th*2]+sum[th*2+1];
}
void UpDate(int L,int R,int v,int l,int r,int th){
if(L<=l&&r<=R){
cover[th]+=v;
//这儿是整个想法的核心,把上边标记成1,下边标记成-1,
//在累加过后直接乘以h,就可以算出面积
PushUp(th,l,r);
return ;//记住return
}
int m=(l+r)/2;
if(m >= L) UpDate(L,R,v,lson);
if(m < R) UpDate(L,R,v,rson);
PushUp(th,l,r);
}
int main(){
int n,m,cas=1;
double x1,y1,x2,y2;
int i,j,k;
while(scanf("%d",&n)!=EOF){
memset(cover,0,sizeof(cover));
memset(sum,0,sizeof(sum));
if(n==0) break;
m=0;
while(n--){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
X[m]=x1;
ll[m++]=line(x1,x2,y1,1);
X[m]=x2;
ll[m++]=line(x1,x2,y2,-1);
}
sort(X,X+m);
sort(ll,ll+m);
//二分前需要先把这个数组处理一下
for(i=1,k=1;i<m;i++){
if(X[i]!=X[i-1]) X[k++]=X[i]; //这样子X[0]还是X[0],写的很精辟
}
double ans=0;//每个值一定要赋初值
for(i=0;i<m-1;i++){
int l=Bin(ll[i].l,k,X);
int r=Bin(ll[i].r,k,X)-1;//为什么要减1呢???这儿对于这个问题一直还有疑问,希望有大牛来解答
//printf("l:%d r:%d ll:%lf rr:%lf\n",l,r,ll[i].l,ll[i].r);
//if(l!=r) UpDate(l,r,0,k-1,1);错!
//if(l<=r) {
/// UpDate(l,r,ll[i].flag,0,k-1,1);
// ans+=(ll[i+1].h-ll[i].h)*sum[1];
//}
if(l<=r)
UpDate(l,r,ll[i].flag,0,k-1,1);
//printf("%lf\n\n",sum[1]);
ans+=(ll[i+1].h-ll[i].h)*sum[1];
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++ , ans);
}
}