链接: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 }