poj1151(Atlantis)& hdu1542 (Atlantis)(线段树+扫描线)

题目地址:poj1151(Atlantis)hdu1542 (Atlantis)

 

题目大意:

     给你N个矩形,求出矩形在平面图构成的面积。

 

解题思路:

     线段数+扫描线。

需要注意:

     记住线段树返回的cnt 是从左往右每条扫描线 投影Y轴的长度,就能很好的理解线段数+扫描线的代码。

推荐博客:线段树辅助——扫描线法计算矩形面积并,这个博客说的是从下到上扫描,离散化x坐标,原理是一样的,我的代码是从左往右扫描,离散化Y坐标以Y坐标建树。

代码:

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <cstdio>
  7 #include <string>
  8 #include <bitset>
  9 #include <vector>
 10 #include <queue>
 11 #include <stack>
 12 #include <cmath>
 13 #include <list>
 14 #include <map>
 15 #include <set>
 16 using namespace std;
 17 /***************************************/
 18 #define ll long long
 19 #define int64 __int64
 20 /***************************************/
 21 const int INF = 0x7f7f7f7f;
 22 const double eps = 1e-8;
 23 const double PIE=acos(-1.0);
 24 const int d1x[]= {0,-1,0,1};
 25 const int d1y[]= {-1,0,1,0};
 26 const int d2x[]= {0,-1,0,1};
 27 const int d2y[]= {1,0,-1,0};
 28 const int fx[]= {-1,-1,-1,0,0,1,1,1};
 29 const int fy[]= {-1,0,1,-1,1,-1,0,1};
 30 /***************************************/
 31 void openfile()
 32 {
 33     freopen("data.in","rb",stdin);
 34     freopen("data.out","wb",stdout);
 35 }
 36 /**********************华丽丽的分割线,以上为模板部分*****************/
 37 const int M=300;
 38 
 39 struct tree
 40 {
 41     int left,right;  //左右区间
 42     double turel,turer,cnt; //记录左右区间的真实值和 投影Y轴坐标的覆盖的程度cnt
 43     int c;  //记录该区间被覆盖几次。
 44 
 45 } node[M*4];
 46 struct Line
 47 {
 48     double x,y1,y2;    //记录每一条扫描线
 49     int f;  //标记入边1,出边为-1
 50 }line[M];  //储存所有的线段
 51 int cnt;
 52 double y[M];  //将y的坐标记录然后离散化
 53 bool cmp(Line a,Line b)  //排序 
 54 {
 55     return a.x<b.x;
 56 } 
 57 void build__tree(int id,int l,int r)  //初始化树
 58 {
 59     int mid=(l+r)/2;
 60     node[id].turel=y[l];
 61     node[id].turer=y[r];
 62     node[id].left=l;
 63     node[id].right=r;
 64     node[id].cnt=0;
 65     node[id].c=0;
 66     if (l+1==r)
 67         return ;
 68     build__tree(id*2,l,mid);
 69     build__tree(id*2+1,mid,r);
 70 }
 71 void upcnt(int id)   //更新投影Y轴的线段
 72 {
 73     if (node[id].c>0)
 74     {
 75         node[id].cnt=node[id].turer-node[id].turel;
 76         return ;
 77     }
 78     if (node[id].left+1==node[id].right)
 79         node[id].cnt=0;
 80     else
 81         node[id].cnt=node[id*2].cnt+node[id*2+1].cnt;
 82 }
 83 void updata(int id,Line v)
 84 {
 85     if (node[id].turel==v.y1&&node[id].turer==v.y2)
 86     {
 87         node[id].c+=v.f;
 88         upcnt(id);
 89         return ;
 90     }
 91     if (v.y2<=node[id*2].turer)
 92         updata(id*2,v);
 93     else if (v.y1>=node[id*2+1].turel)
 94         updata(id*2+1,v);
 95     else
 96     {
 97         Line tmp;
 98         tmp=v;
 99         tmp.y2=node[id*2].turer;
100         updata(id*2,tmp);
101         tmp=v;
102         tmp.y1=node[id*2+1].turel;
103         updata(id*2+1,tmp);
104     }
105     upcnt(id);
106 }
107 
108 int main()
109 {
110     int n;
111     int icas=0;
112     while(scanf("%d",&n)&&n)
113     {
114         int i,j;
115         int d=1;
116         for(i=1;i<=n;i++)
117         {
118             double x1,x2,y1,y2;
119             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
120             line[d].x=x1;
121             line[d].y1=y1;
122             line[d].y2=y2;
123             line[d].f=1;
124             y[d]=y1;
125             d++;
126             line[d].x=x2;
127             line[d].y1=y1;
128             line[d].y2=y2;
129             line[d].f=-1;
130             y[d]=y2;
131             d++;
132         }
133         sort(y+1,y+d);
134         sort(line+1,line+d,cmp);
135         build__tree(1,1,d-1);
136         updata(1,line[1]);
137         double sum=0;
138         for(i=2;i<d;i++)
139         {
140             sum+=node[1].cnt*(line[i].x-line[i-1].x);
141             updata(1,line[i]);
142         }
143         printf("Test case #%d\n",++icas);
144         printf("Total explored area: %.2lf\n\n",sum);
145     }
146     return 0;
147 }
View Code

 

posted @ 2014-11-12 21:04  kinghold  Views(182)  Comments(0Edit  收藏  举报