poj 1151 poj 1389 线段树+扫描线+离散化 [矩形的面积并]
2014-10-14 10:50
323 查看
Atlantis
题意:求矩形的面积并
解法:
扫描线+线段树维护+离散化
扫描矩形左右边界,左边为入边,右边为出边,使用线段树维护段中的覆盖长度即可
离散化y坐标,进行线段树的左右边界维护
不同于传统的建树,左树为 [l,mid],右树为[mid,r];//为了相减方便**//比如 [1,2][2,4],这样的建立方式,当插入[1,4]时,得出的len值为1+2,但是传统的建图[1,2][3,4]得到的len=2
可以参考这个博文对于扫描线的分析yuzhou627
[poj1151.cpp]
#include<iostream> #include<cstring> #include <algorithm> #include<cstdlib> #include<vector> #include<cmath> #include<stdlib.h> #include<iomanip> #include<list> #include<deque> #include<map> #include <stdio.h> #include <queue> #define maxn 5000+5 #define inf 0x3f3f3f3f #define INF 0x3FFFFFFFFFFFFFFFLL #define rep(i,n) for(i=0;i<n;i++) #define reP(i,n) for(i=1;i<=n;i++) #define ull unsigned long long #define ll long long #define LL(x) x<<1 #define RR(x) x<<1|1 #define cle(a) memset(a,0,sizeof(a)) using namespace std; struct Line{//扫描线 double x,upy,downy; int flag; Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){} Line(){} }line[maxn]; struct node{ int l,r,flag; double ly,ry,len; int Mid(){ return (l+r)>>1; } }tree[maxn<<2]; double hash[maxn]; bool cmp(Line a,Line b){return a.x<b.x; } void build(int rt,int l,int r){ tree[rt].l=l,tree[rt].r=r; tree[rt].ly=hash[l],tree[rt].ry=hash[r]; tree[rt].flag=0,tree[rt].len=0; if(tree[rt].l+1==tree[rt].r)return; int mid=(l+r)>>1; build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1, } void doit(int x){//更新覆盖段 if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly; else if(tree[x].l+1==tree[x].r)tree[x].len=0; else tree[x].len=tree[RR(x)].len+tree[LL(x)].len; } void update(int rt,Line a){//更新 if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){ tree[rt].flag+=a.flag; doit(rt);return; } if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a); else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a); else{ Line temp=a;temp.downy=tree[LL(rt)].ry; update(LL(rt),temp); temp=a;temp.upy=tree[RR(rt)].ly; update(RR(rt),temp); } doit(rt); return; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int n; int T=1; while(cin>>n&&n){ int i; for(i=1;i<=n;i++){ double a,b,c,d;scanf("%lf%lf%lf%lf",&a,&b,&c,&d); line[2*i-1]=Line(a,b,d,1);line[2*i]=Line(c,b,d,-1); hash[2*i-1]=b,hash[2*i]=d; } sort(line,line+2*n+1,cmp);sort(hash,hash+1+n*2); int m=2*n; build(1,1,m);update(1,line[1]); double ans=0.0; for(i=2;i<=m;i++){ ans+=(tree[1].len)*(line[i].x-line[i-1].x); update(1,line[i]); } printf("Test case #%d\nTotal explored area: %.2f\n\n",T++,ans); } return 0; }
[poj1389.cpp]
/************************************************************************* > File Name: poj1389.cpp > Author: cy > Mail: 1002@qq.com > Created Time: 14/10/14 11:02:43 ************************************************************************/ #include<iostream> #include<cstring> #include <algorithm> #include<cstdlib> #include<vector> #include<cmath> #include<stdlib.h> #include<iomanip> #include<list> #include<deque> #include<map> #include <stdio.h> #include <queue> #define maxn 5000+5 #define inf 0x3f3f3f3f #define INF 0x3FFFFFFFFFFFFFFFLL #define rep(i,n) for(i=0;i<n;i++) #define reP(i,n) for(i=1;i<=n;i++) #define ull unsigned long long #define ll long long #define LL(x) x<<1 #define RR(x) x<<1|1 #define cle(a) memset(a,0,sizeof(a)) using namespace std; struct Line{//扫描线 double x,upy,downy; int flag; Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){} Line(){} }line[maxn]; struct node{ int l,r,flag; double ly,ry,len; int Mid(){ return (l+r)>>1; } }tree[maxn<<2]; double hash[maxn]; bool cmp(Line a,Line b){return a.x<b.x; } void build(int rt,int l,int r){ tree[rt].l=l,tree[rt].r=r; tree[rt].ly=hash[l],tree[rt].ry=hash[r]; tree[rt].flag=0,tree[rt].len=0; if(tree[rt].l+1==tree[rt].r)return; int mid=(l+r)>>1; build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1, } void doit(int x){//更新覆盖段 if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly; else if(tree[x].l+1==tree[x].r)tree[x].len=0; else tree[x].len=tree[RR(x)].len+tree[LL(x)].len; } void update(int rt,Line a){//更新 if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){ tree[rt].flag+=a.flag; doit(rt);return; } if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a); else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a); else{ Line temp=a;temp.downy=tree[LL(rt)].ry; update(LL(rt),temp); temp=a;temp.upy=tree[RR(rt)].ly; update(RR(rt),temp); } doit(rt); return; } bool getend(double a,double b,double c,double d){ if(a==-1&&b==-1&&c==-1&&d==-1)return true; return false; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int i; double a,b,c,d; int T=1; while(true){ while(scanf("%lf%lf%lf%lf",&a,&b,&c,&d)){ if(getend(a,b,c,d)){ break; } line[2*T-1]=Line(a,b,d,1);line[2*T]=Line(c,b,d,-1); hash[2*T-1]=b,hash[2*T]=d; T++; } if(T==1)return 0; T--; sort(line,line+2*T+1,cmp);sort(hash,hash+1+T*2); int m=2*T; build(1,1,m);update(1,line[1]); double ans=0.0; for(i=2;i<=m;i++){ ans+=(tree[1].len)*(line[i].x-line[i-1].x); update(1,line[i]); } printf("%.0f\n",ans); T=1; } return 0; }
相关文章推荐
- POJ 1151 && 1389 离散化求矩形面积的并
- poj 1151 Atlantis(矩形面积并,线段树+离散化)
- poj 1151(离散化+矩形面积并)
- HDU-1542/POJ-1151 Atlantis(矩形并面积--线段树+离散化)
- poj 1389 线段树+扫描线 求矩形交的面积
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
- 【线段树 + 离散化 + 扫描线】poj 1151 Atlantis 矩形面积并
- POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]
- poj 1151 线段树+扫描线(Atlantis矩形面积)
- POJ-1151-Atlantis-求矩形面积并(线段树+扫描线)
- poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)
- poj 1151 线段树+离散化+扫描线 (矩形面积并
- POJ 1389 Area of Simple Polygons (离散化求矩形面积并)
- POJ 1389 Area of Simple Polygons(多矩形重叠面积==离散化)
- POJ 1151 Atlantis (离散化求矩形面积并)
- poj 1151 && hdu 1542 离散化求矩形面积的并
- poj 1151 线段树+离散化+扫描线 矩形面积并 (矩阵操作类)
- poj 1151 线段树求矩形面积的并
- POJ 1151 Atlantis(扫描线 + 线段树 矩形面积的并)
- poj 1151 Atlantis 纯矩形面积并