poj 1151 poj 1389 线段树+扫描线+离散化 [矩形的面积并]

Atlantis



题意:求矩形的面积并


解法:


  • 扫描线+线段树维护+离散化
  • 扫描矩形左右边界,左边为入边,右边为出边,使用线段树维护段中的覆盖长度即可
  • 离散化y坐标,进行线段树的左右边界维护

    不同于传统的建树,左树为 [l,mid],右树为[mid,r];//为了相减方便**
    //比如 [1,2][2,4],这样的建立方式,当插入[1,4]时,得出的len值为1+2,但是传统的建图[1,2][3,4]得到的len=2


可以参考这个博文对于扫描线的分析yuzhou627


[poj1151.cpp]

 
 
  1. #include<iostream> 
  2. #include<cstring> 
  3. #include <algorithm> 
  4. #include<cstdlib> 
  5. #include<vector> 
  6. #include<cmath> 
  7. #include<stdlib.h> 
  8. #include<iomanip> 
  9. #include<list> 
  10. #include<deque> 
  11. #include<map> 
  12. #include <stdio.h> 
  13. #include <queue> 
  14.  
  15. #define maxn 5000+5 
  16.  
  17. #define inf 0x3f3f3f3f 
  18.   #define INF 0x3FFFFFFFFFFFFFFFLL 
  19. #define rep(i,n) for(i=0;i<n;i++) 
  20.  #define reP(i,n) for(i=1;i<=n;i++) 
  21.  
  22. #define ull unsigned long long 
  23.  #define ll long long 
  24.  
  25. #define LL(x) x<<1 
  26.    #define RR(x)  x<<1|1 
  27.  
  28. #define cle(a) memset(a,0,sizeof(a)) 
  29.  
  30. using namespace std; 
  31. struct Line{//扫描线 
  32.     double x,upy,downy; 
  33.     int flag; 
  34.     Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){} 
  35.     Line(){}     
  36. }line[maxn]; 
  37. struct node{ 
  38.     int l,r,flag; 
  39.     double ly,ry,len; 
  40.     int Mid(){ 
  41.         return (l+r)>>1
  42.     } 
  43. }tree[maxn<<2]; 
  44. double hash[maxn]; 
  45. bool cmp(Line a,Line b){return a.x<b.x; 
  46. void build(int rt,int l,int r){ 
  47.     tree[rt].l=l,tree[rt].r=r; 
  48.     tree[rt].ly=hash[l],tree[rt].ry=hash[r]; 
  49.     tree[rt].flag=0,tree[rt].len=0
  50.     if(tree[rt].l+1==tree[rt].r)return
  51.     int mid=(l+r)>>1
  52.     build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1, 
  53. void doit(int x){//更新覆盖段 
  54.     if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly; 
  55.     else if(tree[x].l+1==tree[x].r)tree[x].len=0
  56.     else tree[x].len=tree[RR(x)].len+tree[LL(x)].len; 
  57. void update(int rt,Line a){//更新 
  58.     if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){ 
  59.         tree[rt].flag+=a.flag; 
  60.         doit(rt);return
  61.     } 
  62.     if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a); 
  63.     else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a); 
  64.     else
  65.         Line temp=a;temp.downy=tree[LL(rt)].ry; 
  66.         update(LL(rt),temp); 
  67.         temp=a;temp.upy=tree[RR(rt)].ly; 
  68.         update(RR(rt),temp); 
  69.     } 
  70.     doit(rt); 
  71.     return
  72. int main() 
  73. #ifndef ONLINE_JUDGE 
  74.      freopen("in.txt","r",stdin); 
  75.      //freopen("out.txt","w",stdout); 
  76. #endif 
  77.     int n; 
  78.     int T=1
  79.     while(cin>>n&&n){ 
  80.         int i; 
  81.         for(i=1;i<=n;i++){ 
  82.             double a,b,c,d;scanf("%lf%lf%lf%lf",&a,&b,&c,&d); 
  83.             line[2*i-1]=Line(a,b,d,1);line[2*i]=Line(c,b,d,-1); 
  84.             hash[2*i-1]=b,hash[2*i]=d; 
  85.         } 
  86.         sort(line,line+2*n+1,cmp);sort(hash,hash+1+n*2); 
  87.         int m=2*n; 
  88.         build(1,1,m);update(1,line[1]); 
  89.         double ans=0.0
  90.         for(i=2;i<=m;i++){ 
  91.             ans+=(tree[1].len)*(line[i].x-line[i-1].x); 
  92.             update(1,line[i]); 
  93.         } 
  94.         printf("Test case #%d\nTotal explored area: %.2f\n\n",T++,ans); 
  95.     } 
  96.     return 0
  97. }

[poj1389.cpp]

 
 
  1. /************************************************************************* 
  2.     > File Name: poj1389.cpp 
  3.     > Author: cy 
  4.     > Mail: 1002@qq.com  
  5.     > Created Time: 14/10/14 11:02:43 
  6.  ************************************************************************/ 
  7.  
  8. #include<iostream>  
  9. #include<cstring>  
  10. #include <algorithm>  
  11. #include<cstdlib>  
  12. #include<vector>  
  13. #include<cmath>  
  14. #include<stdlib.h>  
  15. #include<iomanip>  
  16. #include<list>  
  17. #include<deque>  
  18. #include<map>  
  19. #include <stdio.h>  
  20. #include <queue>  
  21.  
  22. #define maxn 5000+5  
  23.  
  24. #define inf 0x3f3f3f3f  
  25.   #define INF 0x3FFFFFFFFFFFFFFFLL  
  26. #define rep(i,n) for(i=0;i<n;i++)  
  27.  #define reP(i,n) for(i=1;i<=n;i++)  
  28.  
  29. #define ull unsigned long long  
  30.  #define ll long long  
  31.  
  32. #define LL(x) x<<1  
  33.    #define RR(x)  x<<1|1  
  34.  
  35. #define cle(a) memset(a,0,sizeof(a))  
  36.  
  37. using namespace std;  
  38. struct Line{//扫描线  
  39.     double x,upy,downy;  
  40.     int flag;  
  41.     Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){}  
  42.     Line(){}      
  43. }line[maxn];  
  44. struct node{  
  45.     int l,r,flag;  
  46.     double ly,ry,len;  
  47.     int Mid(){  
  48.         return (l+r)>>1;  
  49.     }  
  50. }tree[maxn<<2];  
  51. double hash[maxn];  
  52. bool cmp(Line a,Line b){return a.x<b.x;  
  53. }  
  54. void build(int rt,int l,int r){  
  55.     tree[rt].l=l,tree[rt].r=r;  
  56.     tree[rt].ly=hash[l],tree[rt].ry=hash[r];  
  57.     tree[rt].flag=0,tree[rt].len=0;  
  58.     if(tree[rt].l+1==tree[rt].r)return;  
  59.     int mid=(l+r)>>1;  
  60.     build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1,  
  61. }  
  62. void doit(int x){//更新覆盖段  
  63.     if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly;  
  64.     else if(tree[x].l+1==tree[x].r)tree[x].len=0;  
  65.     else tree[x].len=tree[RR(x)].len+tree[LL(x)].len;  
  66. }  
  67. void update(int rt,Line a){//更新  
  68.     if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){  
  69.         tree[rt].flag+=a.flag;  
  70.         doit(rt);return;  
  71.     }  
  72.     if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a);  
  73.     else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a);  
  74.     else{  
  75.         Line temp=a;temp.downy=tree[LL(rt)].ry;  
  76.         update(LL(rt),temp);  
  77.         temp=a;temp.upy=tree[RR(rt)].ly;  
  78.         update(RR(rt),temp);  
  79.     }  
  80.     doit(rt);  
  81.     return;  
  82. }  
  83. bool getend(double a,double b,double c,double d){ 
  84.     if(a==-1&&b==-1&&c==-1&&d==-1)return true
  85.     return false
  86. int main()  
  87. {  
  88. #ifndef ONLINE_JUDGE  
  89.      freopen("in.txt","r",stdin);  
  90.      //freopen("out.txt","w",stdout);  
  91. #endif  
  92.         int i;  
  93.         double a,b,c,d; 
  94.         int T=1
  95.         while(true){ 
  96.         while(scanf("%lf%lf%lf%lf",&a,&b,&c,&d)){ 
  97.         if(getend(a,b,c,d)){ 
  98.             break
  99.         } 
  100.         line[2*T-1]=Line(a,b,d,1);line[2*T]=Line(c,b,d,-1);  
  101.         hash[2*T-1]=b,hash[2*T]=d;  
  102.         T++; 
  103.         } 
  104.         if(T==1)return 0
  105.         T--; 
  106.         sort(line,line+2*T+1,cmp);sort(hash,hash+1+T*2);  
  107.         int m=2*T;  
  108.         build(1,1,m);update(1,line[1]);  
  109.         double ans=0.0;  
  110.         for(i=2;i<=m;i++){  
  111.             ans+=(tree[1].len)*(line[i].x-line[i-1].x);  
  112.             update(1,line[i]);  
  113.         }  
  114.         printf("%.0f\n",ans);  
  115.         T=1
  116.         } 
  117.     return 0;  
  118. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值