【HDU 1828】 Picture (矩阵周长并,线段树,扫描法)
【题目】
Picture
Problem DescriptionA number of rectangular posters, photographs and other pictures of the same shape are pasted on a wall. Their sides are all vertical or horizontal. Each rectangle can be partially or totally covered by the others. The length of the boundary of the union of all rectangles is called the perimeter.
Write a program to calculate the perimeter. An example with 7 rectangles is shown in Figure 1.
The corresponding boundary is the whole set of line segments drawn in Figure 2.
The vertices of all rectangles have integer coordinates.
InputYour program is to read from standard input. The first line contains the number of rectangles pasted on the wall. In each of the subsequent lines, one can find the integer coordinates of the lower left vertex and the upper right vertex of each rectangle. The values of those coordinates are given as ordered pairs consisting of an x-coordinate followed by a y-coordinate.
0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.
Please process to the end of file.
OutputYour program is to write to standard output. The output must contain a single line with a non-negative integer which corresponds to the perimeter for the input rectangles.
Sample Input7 -15 0 5 10 -5 8 20 25 15 -4 24 14 0 -6 16 4 2 15 10 22 30 10 36 20 34 0 40 16
Sample Output228
Source
【题意】
看图就懂,求矩形周长并。
【分析】
很容易想到x和y分开搞,其实就是线段的并咯,但是要注意他有退出的一刻。
进去和退出都有可能影响答案,但是不影响答案就不需要加进去ans。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<cmath> 7 using namespace std; 8 #define Maxn 100010 9 10 struct hp 11 { 12 int x1,x2,flag; 13 double y; 14 }t[Maxn*2];int tl; 15 struct lsh 16 { 17 double x; 18 int id; 19 }q[Maxn*2];int ql; 20 21 bool cmp(lsh x,lsh y) {return x.x<y.x;} 22 bool cmp2(hp x,hp y) {return (x.y==y.y)?(x.flag>y.flag):(x.y<y.y);} 23 24 int mymin(int x,int y) {return x<y?x:y;} 25 26 double dis[2*Maxn]; 27 28 struct node 29 { 30 int l,r,lc,rc,cnt; 31 double sm; 32 }tr[Maxn*2];int len; 33 int build(int l,int r) 34 { 35 int x=++len; 36 tr[x].l=l;tr[x].r=r; 37 tr[x].sm=tr[x].cnt=0; 38 if(l<r-1) 39 { 40 int mid=(tr[x].l+tr[x].r)>>1; 41 tr[x].lc=build(l,mid); 42 tr[x].rc=build(mid,r); 43 } 44 else tr[x].lc=tr[x].rc=0; 45 return x; 46 } 47 48 void upd(int x) 49 { 50 int l=tr[x].l,r=tr[x].r,lc=tr[x].lc,rc=tr[x].rc; 51 if(tr[x].cnt>=1) tr[x].sm=dis[r]-dis[l]; 52 else tr[x].sm=tr[lc].sm+tr[rc].sm; 53 } 54 55 void change(int x,int l,int r,int c) 56 { 57 if(tr[x].l==l&&tr[x].r==r) 58 { 59 tr[x].cnt+=c; 60 upd(x); 61 return; 62 } 63 int mid=(tr[x].l+tr[x].r)>>1; 64 if(r<=mid) change(tr[x].lc,l,r,c); 65 else if(l>=mid) change(tr[x].rc,l,r,c); 66 else 67 { 68 change(tr[x].lc,l,mid,c); 69 change(tr[x].rc,mid,r,c); 70 } 71 upd(x); 72 } 73 74 double x1[Maxn],ya[Maxn],x2[Maxn],y2[Maxn]; 75 int n; 76 void init() 77 { 78 for(int i=1;i<=n;i++) scanf("%lf%lf%lf%lf",&x1[i],&ya[i],&x2[i],&y2[i]); 79 } 80 81 double ans; 82 83 void ffind() 84 { 85 tl=0;ql=0; 86 for(int i=1;i<=n;i++) 87 { 88 //t[++tl].x1, 89 t[++tl].flag=1;t[tl].y=ya[i]; 90 t[++tl].flag=-1;t[tl].y=y2[i]; 91 q[++ql].x=x1[i],q[ql].id=tl; 92 q[++ql].x=x2[i],q[ql].id=tl+2*n; 93 } 94 sort(q+1,q+1+ql,cmp); 95 int p=0; 96 for(int i=1;i<=ql;i++) 97 { 98 if(q[i].x!=q[i-1].x||p==0) p++,dis[p]=dis[p-1]+q[i].x-q[i-1].x; 99 if(q[i].id<=2*n) t[q[i].id].x1=t[q[i].id-1].x1=p; 100 else t[q[i].id-2*n].x2=t[q[i].id-1-2*n].x2=p; 101 } 102 sort(t+1,t+1+tl,cmp2); 103 len=0;tr[0].sm=0; 104 build(1,p); 105 double now=0; 106 for(int i=1;i<=tl;i++) 107 { 108 change(1,t[i].x1,t[i].x2,t[i].flag); 109 double nn=tr[1].sm; 110 if(t[i].flag==1) ans+=nn-now; 111 else ans+=now-nn; 112 now=nn; 113 } 114 } 115 116 int main() 117 { 118 int T; 119 // scanf("%d",&T); 120 // T=1; 121 while(scanf("%d",&n)!=EOF) 122 { 123 124 init(); 125 ans=0; 126 ffind(); 127 // printf("%.0lf\n",ans); 128 for(int i=1;i<=n;i++) 129 { 130 double tt; 131 tt=x1[i],x1[i]=ya[i],ya[i]=tt; 132 tt=x2[i],x2[i]=y2[i],y2[i]=tt; 133 } 134 ffind(); 135 printf("%.0lf\n",ans); 136 } 137 return 0; 138 }
ws的题目,谁说了多组啊!!!
哦,对了,有一个比较坑的地方【ORZ。。GDXB
矩形边界重合的时候的处理。举个例子,在处理x轴的时候:
中间那条一次也不算。
这个东西,在排序的时候注意一下就好了。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<cmath> 7 using namespace std; 8 #define Maxn 100010 9 10 struct hp 11 { 12 int x1,x2,flag; 13 double y; 14 }t[Maxn*2];int tl; 15 struct lsh 16 { 17 double x; 18 int id; 19 }q[Maxn*2];int ql; 20 21 bool cmp(lsh x,lsh y) {return x.x<y.x;} 22 bool cmp2(hp x,hp y) {return (x.y==y.y)?(x.flag>y.flag):(x.y<y.y);} 23 24 int mymin(int x,int y) {return x<y?x:y;} 25 26 double dis[2*Maxn]; 27 28 struct node 29 { 30 int l,r,lc,rc,cnt; 31 double sm; 32 }tr[Maxn*2];int len; 33 int build(int l,int r) 34 { 35 int x=++len; 36 tr[x].l=l;tr[x].r=r; 37 tr[x].sm=tr[x].cnt=0; 38 if(l<r-1) 39 { 40 int mid=(tr[x].l+tr[x].r)>>1; 41 tr[x].lc=build(l,mid); 42 tr[x].rc=build(mid,r); 43 } 44 else tr[x].lc=tr[x].rc=0; 45 return x; 46 } 47 48 void upd(int x) 49 { 50 int l=tr[x].l,r=tr[x].r,lc=tr[x].lc,rc=tr[x].rc; 51 if(tr[x].cnt>=1) tr[x].sm=dis[r]-dis[l]; 52 else tr[x].sm=tr[lc].sm+tr[rc].sm; 53 } 54 55 void change(int x,int l,int r,int c) 56 { 57 if(tr[x].l==l&&tr[x].r==r) 58 { 59 tr[x].cnt+=c; 60 upd(x); 61 return; 62 } 63 int mid=(tr[x].l+tr[x].r)>>1; 64 if(r<=mid) change(tr[x].lc,l,r,c); 65 else if(l>=mid) change(tr[x].rc,l,r,c); 66 else 67 { 68 change(tr[x].lc,l,mid,c); 69 change(tr[x].rc,mid,r,c); 70 } 71 upd(x); 72 } 73 74 double x1[Maxn],ya[Maxn],x2[Maxn],y2[Maxn]; 75 int n; 76 void init() 77 { 78 for(int i=1;i<=n;i++) scanf("%lf%lf%lf%lf",&x1[i],&ya[i],&x2[i],&y2[i]); 79 } 80 81 double ans; 82 83 void ffind() 84 { 85 tl=0;ql=0; 86 for(int i=1;i<=n;i++) 87 { 88 //t[++tl].x1, 89 t[++tl].flag=1;t[tl].y=ya[i]; 90 t[++tl].flag=-1;t[tl].y=y2[i]; 91 q[++ql].x=x1[i],q[ql].id=tl; 92 q[++ql].x=x2[i],q[ql].id=tl+2*n; 93 } 94 sort(q+1,q+1+ql,cmp); 95 int p=0; 96 for(int i=1;i<=ql;i++) 97 { 98 if(q[i].x!=q[i-1].x||p==0) p++,dis[p]=dis[p-1]+q[i].x-q[i-1].x; 99 if(q[i].id<=2*n) t[q[i].id].x1=t[q[i].id-1].x1=p; 100 else t[q[i].id-2*n].x2=t[q[i].id-1-2*n].x2=p; 101 } 102 sort(t+1,t+1+tl,cmp2); 103 len=0;tr[0].sm=0; 104 build(1,p); 105 double now=0; 106 for(int i=1;i<=tl;i++) 107 { 108 change(1,t[i].x1,t[i].x2,t[i].flag); 109 double nn=tr[1].sm; 110 if(t[i].flag==1) ans+=nn-now; 111 else ans+=now-nn; 112 now=nn; 113 } 114 } 115 116 int main() 117 { 118 int T; 119 // scanf("%d",&T); 120 // T=1; 121 while(scanf("%d",&n)!=EOF) 122 { 123 124 init(); 125 ans=0; 126 ffind(); 127 // printf("%.0lf\n",ans); 128 for(int i=1;i<=n;i++) 129 { 130 double tt; 131 tt=x1[i],x1[i]=ya[i],ya[i]=tt; 132 tt=x2[i],x2[i]=y2[i],y2[i]=tt; 133 } 134 ffind(); 135 printf("%.0lf\n",ans); 136 } 137 return 0; 138 }
2016-11-10 15:49:48