标签:des style blog http io ar color os sp
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 18061 | Accepted: 6873 |
Description
Input
Output
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
求矩形覆盖下的面积。可以把矩形平行y轴的线段都删去,这样就剩下很多平行x轴的线段。把线段y值按从小到大排序,每次插入一条线段得到当前覆盖在x轴的长度,乘以该条线段和下一条线段的z纵坐标之差,就是面积。求和即可。见下图
#include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> #include<vector> #include<queue> #include<algorithm> using namespace std; #define N 410 #define ll __int64 double x[N]; struct line //记录和x轴平行的线段信息 { int f; //f为0、1代表为底边或顶边 double x1,x2,y; // 线段从左到右的端点,在y轴上的位置 }a[N]; struct node //线段树结构体 { int f; //记录该区间是否重叠 double l,r,len; //记录区间的左右端点,和实际覆盖长度 }f[N*3]; bool cmp(line a,line b) { return a.y<b.y; } void creat(int t,int l,int r) { f[t].l=x[l]; f[t].r=x[r]; f[t].len=f[t].f=0; if(l==r-1) return ; int tmp=t<<1,mid=(l+r)>>1; creat(tmp,l,mid); creat(tmp|1,mid,r); //线段是连续的,长度为f[t].r-f[t].l } void pushup(int t) { if(f[t].f) f[t].len=f[t].r-f[t].l; else f[t].len=f[t<<1].len+f[t<<1|1].len; } void update(int t,line a) { if(f[t].l==a.x1&&f[t].r==a.x2) { f[t].f+=a.f; pushup(t); return ; } int tmp=t<<1; if(a.x2<=f[tmp].r) //线段落在左边子区间 update(tmp,a); else if(a.x1>=f[tmp|1].l) ////线段落在右边子区间 update(tmp|1,a); else // 线段落在左右子区间 { line b=a; //拆分线段为两段分属两个区间 b.x2=f[tmp].r; update(tmp,b); b=a; b.x1=f[tmp].r; update(tmp|1,b); } pushup(t); //向父节点求和 } int main() { int i,n,cnt=1,m; double x1,x2,y1,y2; while(scanf("%d",&n),n) { for(i=m=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); a[m].x1=x1; a[m].x2=x2; a[m].y=y1; a[m].f=1; x[m++]=x1; a[m].x1=x1; a[m].x2=x2; a[m].y=y2; a[m].f=-1; x[m++]=x2; } sort(x+1,x+m); //排序 sort(a+1,a+m,cmp); creat(1,1,m-1); update(1,a[1]); double ans=0; for(i=2;i<m;i++) { ans+=f[1].len*(a[i].y-a[i-1].y); update(1,a[i]); } printf("Test case #%d\n",cnt++); printf("Total explored area: %.2f\n\n",ans); } return 0; }
poj 1151 Atlantis (线段树+扫描线+离散化)
标签:des style blog http io ar color os sp
原文地址:http://blog.csdn.net/u011721440/article/details/41801145