hdu1828[扫描线矩形周长并]

来源:互联网 发布:淘宝销售统计 编辑:程序博客网 时间:2024/06/10 09:27

Picture
Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u

Submit Status

Description

A 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.
 

Input

Your 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.


题意:给一些矩形,求周长并。


我才用了笨笨的办法,扫了2次,每次求单个方向上的矩形周长并。

用一个变量储存上次扫到的总的覆盖区间长,然后计算当前的,变化的绝对值就是周长的一小截(至于为什么是周长的绝对值,可以画图看看)

然后就按照扫描线矩形面积并的方案类似的处理,就只有计算哪里不同而已。


(PS:吐血的是,我写矩形面积并一般不考虑最后一条边,懒得特判,但这里不同,需要最后一条边,我开始没加,答案就少了一点,还是调试出来的- -)

记录:

PS:不知道为什么x1,y1,x2,y2被警告是函数- -  改成了大写才过的    求大神解释

AC代码:


#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#include<vector>const int maxn=5000+20;const int k=1;using namespace std;int X1[maxn],Y1[maxn],X2[maxn],Y2[maxn];int n;struct line{int x,Y1,Y2,flag;line(int x,int Y1,int Y2,int flag){this->x=x;this->Y1=Y1;this->Y2=Y2;this->flag=flag;}bool operator<(const line &p)const {return x<p.x;}};vector<line>L;int det[2*maxn];int tot;int find(int x){return lower_bound(det+1,det+tot+1,x)-det;}struct node{int l,r,flag;int len[5];void set(int l,int r,int flag){this->l=l;this->r=r;this->flag=flag;}}T[8*maxn];int ans;void pushup(int i){int l=T[i].l;int r=T[i].r;for(int j=0;j<=k;j++)T[i].len[j]=0;if(l==r){int t=min(T[i].flag,k);T[i].len[t]=det[l+1]-det[l];}else{for(int j=0;j<=k;j++){int t=min(T[i].flag+j,k);T[i].len[t]+=T[i<<1].len[j]+T[i<<1|1].len[j];}}}void build(int i,int l,int r){T[i].set(l,r,0);if(l==r){pushup(i);return ;}int mid=(l+r)>>1;build(i<<1,l,mid);build(i<<1|1,mid+1,r);pushup(i);}void updata(int i,int L,int R,int x){int l=T[i].l;int r=T[i].r;if(l>=L&&r<=R){T[i].flag+=x;pushup(i);return ;}int mid=(l+r)>>1;if(L<=mid)updata(i<<1,L,R,x);if(R>mid)updata(i<<1|1,L,R,x);pushup(i);}void work(){tot=0;L.clear();for(int i=1;i<=n;i++){L.push_back(line(X1[i],Y1[i],Y2[i],1));L.push_back(line(X2[i],Y1[i],Y2[i],-1));det[++tot]=Y1[i];det[++tot]=Y2[i];}sort(L.begin(),L.end());sort(det+1,det+tot+1);int t=tot;tot=unique(det+1,det+t+1)-det-1;build(1,1,tot);int pre=0;for(int i=0;i<L.size();i++){int l=find(L[i].Y1);int r=find(L[i].Y2);updata(1,l,r-1,L[i].flag);ans+=abs(pre-T[1].len[k]);pre=T[1].len[k];}}int main(){while(scanf("%d",&n)!=EOF){ans=0;for(int i=1;i<=n;i++){scanf("%d%d%d%d",&X1[i],&Y1[i],&X2[i],&Y2[i]);}work();for(int i=1;i<=n;i++){swap(X1[i],Y1[i]);swap(X2[i],Y2[i]);}work();printf("%d\n",ans);}return 0;}



1 0
原创粉丝点击