HDU 1255 覆盖的面积

覆盖的面积

Time Limit: 5000ms
Memory Limit: 32768KB
This problem will be judged on  HDU. Original ID: 1255
64-bit integer IO format: %I64d      Java class name: Main
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.

HDU 1255 覆盖的面积

 

Input

输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.

注意:本题的输入数据较多,推荐使用scanf读入数据.
 

Output

对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.
 

Sample Input

2

5

1 1 4 2

1 3 3 7

2 1.5 5 4.5

3.5 1.25 7.5 4

6 3 10 7

3

0 0 1 1

1 0 2 1

2 0 3 1

Sample Output

7.63

0.00

解题:离散化,扫面线求矩形面积的交。。关键是如何更新覆盖两次以上的区间。

如果当前区间覆盖次数超过一次,那么区间长度就是差了,如果覆盖次数是1呢,那么看左儿子与右儿子,覆盖至少一次的长度,这两个加起来,即覆盖至少两次的长度。。。。

其余的跟一般的求面积并没什么区别了。。。

ps:此题的题面貌似有误,应该是先左下角,再右上角,还有第一个样例保留两位小数貌似是7.62.。。


HDU 1255 覆盖的面积
 1 #include <bits/stdc++.h>

 2 using namespace std;

 3 const int maxn = 100000;

 4 struct node{

 5     int lt,rt,cover;

 6     double s,ss;

 7 }tree[maxn<<2];

 8 struct Line{

 9     double x1,x2,y;

10     int delta;

11     Line(){}

12     Line(double xx,double xxx,double yy,int dt){

13         x1 = xx;

14         x2 = xxx;

15         y = yy;

16         delta = dt;

17     }

18     bool operator<(const Line &t)const{

19         return y < t.y;

20     }

21 };

22 vector<Line>line;

23 vector<double>d;

24 void build(int lt,int rt,int v){

25     tree[v].lt = lt;

26     tree[v].rt = rt;

27     tree[v].cover = 0;

28     tree[v].s = tree[v].ss = 0;

29     if(lt + 1 == rt) return;

30     int mid = (lt + rt)>>1;

31     build(lt,mid,v<<1);

32     build(mid,rt,v<<1|1);

33 }

34 void pushUp(int v){

35     if(tree[v].cover) tree[v].s = d[tree[v].rt] - d[tree[v].lt];

36     else if(tree[v].lt + 1 == tree[v].rt) tree[v].s = 0;

37     else tree[v].s = tree[v<<1].s + tree[v<<1|1].s;

38 

39     if(tree[v].cover > 1) tree[v].ss = d[tree[v].rt] - d[tree[v].lt];

40     else if(tree[v].lt + 1 == tree[v].rt) tree[v].ss = 0;

41     else if(tree[v].cover == 1) tree[v].ss = tree[v<<1].s + tree[v<<1|1].s;

42     else tree[v].ss = tree[v<<1].ss + tree[v<<1|1].ss;

43 }

44 void update(int lt,int rt,int delta,int v){

45     if(lt <= tree[v].lt && rt >= tree[v].rt){

46         tree[v].cover += delta;

47         pushUp(v);

48         return;

49     }

50     if(lt < tree[v<<1].rt) update(lt,rt,delta,v<<1);

51     if(rt > tree[v<<1|1].lt) update(lt,rt,delta,v<<1|1);

52     pushUp(v);

53 }

54 int main(){

55     int T,n;

56     double x1,y1,x2,y2;

57     scanf("%d",&T);

58     while(T--){

59         scanf("%d",&n);

60         line.clear();

61         d.clear();

62         for(int i = 0; i < n; ++i){

63             scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);

64             d.push_back(x1);

65             d.push_back(x2);

66             line.push_back(Line(x1,x2,y1,1));

67             line.push_back(Line(x1,x2,y2,-1));

68         }

69         sort(line.begin(),line.end());

70         sort(d.begin(),d.end());

71         d.erase(unique(d.begin(),d.end()),d.end());

72         double ret = 0;

73         build(0,d.size()-1,1);

74         for(int i = 0; i < line.size(); ++i){

75             if(i) ret += (line[i].y - line[i-1].y)*tree[1].ss;

76             int x = lower_bound(d.begin(),d.end(),line[i].x1)-d.begin();

77             int y = lower_bound(d.begin(),d.end(),line[i].x2)-d.begin();

78             update(x,y,line[i].delta,1);

79         }

80         printf("%.2f\n",ret);

81     }

82     return 0;

83 }
View Code

 

你可能感兴趣的:(HDU)