HDU 1542 -Atlantis(线扫描)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542

题意:给你n个矩形,求它们覆盖的面积为多少。(注意输出有要求:在 每个测试例子之后输出一个空行)///由于这里的原因让自己PE了一发

这是赤裸裸的线扫描问题,没有一点地方可以小心的,除了上述说的输出格式的要求。

线扫描其实就是线段树的一种技巧。

  1 #include<cstdio>
  2 #include<algorithm>
  3 
  4 using namespace std;
  5 #define lson id*2
  6 #define rson id*2+1
  7 const int maxn=200+5;
  8 int n;
  9 double x[maxn];
 10 
 11 struct Line
 12 {
 13     double x1,x2,y;///线段的左右端点的值以及高度
 14     operator<(const Line &a)const
 15     {
 16         return y<a.y;
 17     }///升序排列
 18     int flag;///标记线段是矩形得到下边(1)还是上边(-1)
 19 }line[maxn];
 20 
 21 struct Trie
 22 {
 23     int l,r;///线段树的左右端点
 24     double dl,dr;///线段的左右端点的值
 25     double len;///线段的长度
 26     int cov;///线段被覆盖的次数
 27 }a[maxn*4];
 28 
 29 void Get_Len(int id)
 30 {
 31     if(a[id].cov>0)
 32         a[id].len=a[id].dr-a[id].dl;
 33     else if(a[id].l+1==a[id].r)
 34         a[id].len=0;
 35     else
 36         a[id].len=a[lson].len+a[rson].len;
 37 }
 38 void Build(int id,int l,int r)
 39 {
 40     a[id].cov=0;
 41     a[id].dl=x[l];
 42     a[id].dr=x[r];
 43     a[id].l=l;
 44     a[id].r=r;
 45     a[id].len=0;
 46     if(l+1==r)
 47         return ;
 48     int  mid=(l+r)/2;
 49     Build(lson,l,mid);
 50     Build(rson,mid,r);
 51 }
 52 void Updata(int id,Line va)
 53 {
 54     if(a[id].dl>=va.x1&&a[id].dr<=va.x2)
 55     {
 56         a[id].cov+=va.flag;
 57         Get_Len(id);
 58         return ;
 59     }
 60     if(a[lson].dr>=va.x2)
 61         Updata(lson,va);
 62     else if(a[rson].dl<=va.x1)
 63         Updata(rson,va);
 64     else
 65     {
 66         Line tep=va;
 67         tep.x2=a[lson].dr;
 68         Updata(lson,tep);
 69 
 70         tep=va;
 71         tep.x1=a[rson].dl;
 72         Updata(rson,tep);
 73     }
 74     Get_Len(id);
 75 }
 76 int main()
 77 {
 78     int Case=0;
 79     while(~scanf("%d",&n)&&n)
 80     {
 81         int t=0;
 82         for(int i=1;i<=n;i++)
 83         {
 84             double x1,y1,x2,y2;
 85             scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
 86             t++;
 87             line[t].x1=x1;
 88             line[t].x2=x2;
 89             line[t].flag=1;
 90             line[t].y=y1;
 91             x[t]=x1;
 92 
 93             t++;
 94             line[t].x1=x1;
 95             line[t].x2=x2;
 96             line[t].flag=-1;
 97             line[t].y=y2;
 98             x[t]=x2;
 99         }
100         sort(x+1,x+1+t);
101         sort(line+1,line+1+t);
102         Build(1,1,t);
103         Updata(1,line[1]);
104         double ans=0;
105         for(int i=2;i<=t;i++)
106         {
107             ans+=a[1].len*(line[i].y-line[i-1].y);
108             Updata(1,line[i]);
109         }
110         printf("Test case #%d\n",++Case);
111         printf("Total explored area: %.2f\n\n",ans);///注意这里的格式
112     }
113     return 0;
114 }

 

posted @ 2018-03-03 15:02  孟加拉国  阅读(125)  评论(0编辑  收藏  举报