线段树求面积 HDU 1542 HDU 1255
来源:互联网 发布:药物研发管理 软件 编辑:程序博客网 时间:2024/06/16 06:27
参考:http://m.blog.csdn.net/tomorrowtodie/article/details/52048323
HDU 1542 求并的面积。博客里讲的很好。就是从下往上扫,然后线段树维护横坐标的总长度。
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int maxn = 105;double v[maxn<<3];int f[maxn<<3];//v长度,f有没有被覆盖。struct edge{ double x1,x2; double h; int f;}e[maxn<<1];double x[maxn<<1];bool cmp(edge e1,edge e2){ return e1.h<e2.h;}void sert(int i,int a,int b,int f1,int l,int r){ if(l==a&&r==b) { f[i]+=f1; if(f[i]>=1) v[i]=x[b+1]-x[a]; if(f[i]==0){ if(a!=b) v[i]=v[i<<1]+v[i<<1|1]; else v[i]=0; } return ; } int mid=(l+r)>>1; if(b<=mid) sert(i<<1,a,b,f1,l,mid); else if(a>=mid+1) sert(i<<1|1,a,b,f1,mid+1,r); else { sert(i<<1,a,mid,f1,l,mid); sert(i<<1|1,mid+1,b,f1,mid+1,r); } if(f[i]<1) v[i]=v[i<<1]+v[i<<1|1];}int main(){ int n; int case1=1; while(scanf("%d",&n)!=EOF&&n) { memset(e,0,sizeof(e)); memset(v,0,sizeof(v)); memset(f,0,sizeof(f)); memset(x,0,sizeof(x)); int h=0,k=0; for(int i=0;i<n;i++) { double x1,y1,x2,y2; scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); e[h].x1=x1,e[h].x2=x2;e[h].h=y1;e[h].f=1;h++; e[h].x1=x1,e[h].x2=x2;e[h].h=y2;e[h].f=-1;h++; x[k++]=x1,x[k++]=x2; } sort(x,x+k); k=unique(x,x+k)-x; sort(e,e+h,cmp); double ans=0.0; printf("Test case #%d\n",case1++); printf("Total explored area: "); for(int i=0;i<h;i++) { int l=lower_bound(x,x+k,e[i].x1)-x; int r=lower_bound(x,x+k,e[i].x2)-x-1; sert(1,l,r,e[i].f,0,k-1); if(i!=h-1) ans+=(e[i+1].h-e[i].h)*v[1]; } printf("%.2f\n\n",ans); } return 0;}
HDU 1255 求交的面积。
想复杂了,然后很多情况。。
我开始想的是,用v存横坐标的总长度(和求并面积一样),然后用len存重合的横坐标的总长度。然后每次,如果f[i]>1的话 ,表示len[i]=v[i]。如果f[i]==1的时候,我不知道这个时候有没有重合的,,然后我想,如果在i爸爸们,有f[i]>=1,表示len[i]=v[i]。那f[i]==0的时候,len[i]=len[i<<1]+len[i<<1|1];那么删边的时候,如果这个f[i]==1呢,开始为2,我的len[i]不是要变么,那就往下更新,一直找到下一个f[i]>=1的位置。。。
其实就是三种情况。。
f[i]>=2 len[i]=v[i];
f[i]==1 len[i]=v[i<<1]+v[i<<1|1];(a!=b)
len[i]=0;(a==b)
f[i]=0 len[i]=len[i<<1]+len[i<<1|1];(a!=b)
len[i]=0;(a==b)
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cmath>using namespace std;const int maxn = 1005;double v[maxn<<3],len[maxn<<3];//v,覆盖面积,len,交叉面积int f[maxn<<3];struct edge{ double x1,x2; double h; int f;}e[maxn<<1];double x[maxn<<1];bool cmp(edge e1,edge e2){ return e1.h<e2.h;}void sert(int i,int a,int b,int f1,int l,int r){ if(a==l&&b==r) { f[i]+=f1; if(f[i]>0) v[i]=x[b+1]-x[a]; else { if(a==b) v[i]=0; else v[i]=v[i<<1]+v[i<<1|1]; } if(f[i]>=2) len[i]=v[i]; else if(f[i]==1){if(a!=b) len[i]=v[i<<1]+v[i<<1|1]; else len[i]=0;} else { if(a!=b) len[i]=len[i<<1]+len[i<<1|1]; else len[i]=0; } return ; } int mid=(l+r)>>1; if(b<=mid) sert(i<<1,a,b,f1,l,mid); else if(a>=mid+1) sert(i<<1|1,a,b,f1,mid+1,r); else { sert(i<<1,a,mid,f1,l,mid); sert(i<<1|1,mid+1,b,f1,mid+1,r); } if(f[i]<1) v[i]=v[i<<1]+v[i<<1|1]; else v[i]=x[r+1]-x[l]; if(f[i]>=2) len[i]=v[i]; else if(f[i]==1) len[i]=v[i<<1]+v[i<<1|1]; else len[i]=len[i<<1]+len[i<<1|1];}int main(){ int T; scanf("%d",&T); while(T--) { memset(v,0,sizeof(v)); memset(f,0,sizeof(f)); memset(e,0,sizeof(e)); memset(x,0,sizeof(x)); memset(len,0,sizeof(len)); int n; scanf("%d",&n); int h=0,k=0; for(int i=0;i<n;i++) { double x1,y1,x2,y2; scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); e[h].x1=x1,e[h].x2=x2,e[h].h=y1,e[h].f=1;h++; e[h].x1=x1,e[h].x2=x2,e[h].h=y2,e[h].f=-1;h++; x[k++]=x1,x[k++]=x2; } sort(x,x+k); k=unique(x,x+k)-x; sort(e,e+h,cmp); double ans=0; for(int i=0;i<h;i++) { int l=lower_bound(x,x+k,e[i].x1)-x; int r=lower_bound(x,x+k,e[i].x2)-x-1; sert(1,l,r,e[i].f,0,k-1); if(i!=h-1) ans+=len[1]*(e[i+1].h-e[i].h); } printf("%.2f\n",ans); } return 0;}
阅读全文
0 0
- 线段树求面积 HDU 1542 HDU 1255
- hdu 1542 线段树 求面积并
- hdu 2461(线段树求面积并)
- hdu 4052 线段树求面积并
- hdu 1255 线段树 求矩形面积的交
- hdu 1255(线段树求重叠面积)
- hdu 1542 poj/pku 1151(线段树求面积并)
- hdu 1542(线段树 求矩形面积并)Atlantis
- Hdu 1542 Atlantis 线段树 求矩形面积并
- HDU 1542 Atlantis (线段树求矩阵覆盖面积)
- hdu 1542 扫描线+线段树求矩阵面积并
- HDU 1542 Atlantis(线段树求矩形面积并)
- HDU 1542 Atlantis (线段树扫描线求面积并)
- HDU 1542 Atlantis(线段树求矩形面积并)
- hdu 1542 (线段树求矩形面积并)
- hdu 1542 Atlantis (线段树求矩形面积并)
- HDU-1542 Atlantis (线段树 求所有矩形面积和)
- hdu 1542 ,1255 线段树面积并与面积交
- knockout,change事件
- 使用Vysor调试Dragonboard410c
- 史上最详尽平衡树(splay树)讲解
- Spring Boot 入门篇
- C学习笔记
- 线段树求面积 HDU 1542 HDU 1255
- LayerClose弹窗关闭刷新
- Bootstrap 3.3.7学习笔记4
- Eclipse插件 JAVA ResourceBundle Editor安装
- 数据结构课程设计-表达式求值
- plsql注册码激活
- Activity栈管理
- 进程等待及子进程异步等待方式
- 测试执行结果篇