Picture - POJ 1177 扫描线 矩阵合并的周长

来源:互联网 发布:通达oa迁移linux 编辑:程序博客网 时间:2024/05/05 14:15

Picture
Time Limit: 2000MS Memory Limit: 10000KTotal Submissions: 10646 Accepted: 5625

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.

Output

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

7-15 0 5 10-5 8 20 2515 -4 24 140 -6 16 42 15 10 2230 10 36 2034 0 40 16

Sample Output

228

题意:给你n个矩阵,问你矩阵合并之后的图形的周长。

思路:首先就像discuss里面的许多人说的那样,这个测试数据是有问题的。没有考虑到矩阵的边重合的情况,比如

2
0 0 10 10
10 0 20 10
2
0 0 10 10
0 10 10 20

这两组数据,很显然答案应该都是60,我尝试了网上好多人的AC代码,都是一个80,一个60的。

虽然不保证我的代码正确,不过我已经debug3个小时了,应该是没问题的。

扫描线的做法就不多说了。比如算竖边的长度的话,tree[o]中,part表示图形有几个部分,LR表示左右端是否覆盖,lazy=-1表示这个下面的所有节点的值不是一样的,lazy>=0时表示这个下面的所有节点的值都为lazy。

代码如下:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct node1{    int l,r,part,lazy;    bool L,R;}tree[80010];struct node2{    int l,r,f,h;}line[10010];bool cmp(node2 a,node2 b){    return a.h<b.h;}int n,x1[5010],y1[5010],x2[5010],y2[5010],ans;void build(int o,int l,int r){    tree[o].l=l;tree[o].r=r;    tree[o].L=tree[o].R=tree[o].part=0;    tree[o].lazy=-1;    if(l==r)    {        tree[o].lazy=0;        return;    }    int mi=(l+r)/2;    build(o<<1,l,mi);    build(o<<1|1,mi+1,r);}void down(int o){    if(tree[o].l==tree[o].r)      return;    if(tree[o].lazy>=0)    {        tree[o<<1].lazy=tree[o].lazy;tree[o<<1].L=tree[o<<1].R=tree[o].lazy;        tree[o<<1|1].lazy=tree[o].lazy;tree[o<<1|1].L=tree[o<<1|1].R=tree[o].lazy;        tree[o].lazy=-1;    }}void update(int o,int l,int r,int f){    if(tree[o].l==l && tree[o].r==r && tree[o].lazy>=0)    {        tree[o].lazy+=f;        tree[o].L=tree[o].R=tree[o].lazy;        if(tree[o].lazy>0)          tree[o].part=1;        else          tree[o].part=0;        return;    }    down(o);    int mi=(tree[o].l+tree[o].r)/2;    if(r<=mi)      update(o<<1,l,r,f);    else if(l>mi)      update(o<<1|1,l,r,f);    else    {        update(o<<1,l,mi,f);        update(o<<1|1,mi+1,r,f);    }    if(tree[o<<1].lazy==tree[o<<1|1].lazy && tree[o<<1].lazy>=0)      tree[o].lazy=tree[o<<1].lazy;    tree[o].L=tree[o<<1].L;tree[o].R=tree[o<<1|1].R;    tree[o].part=tree[o<<1].part+tree[o<<1|1].part;    if(tree[o<<1].R && tree[o<<1|1].L)      tree[o].part-=1;}void solve(){    build(1,1,20000);    for(int i=1;i<2*n;i++)    {        update(1,line[i].l,line[i].r,line[i].f);        ans+=tree[1].part*2*(line[i+1].h-line[i].h);    }}int main(){    int i,j,k;    while(~scanf("%d",&n))    {        for(i=1;i<=n;i++)        {            scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]);            x1[i]+=10000;x2[i]+=10000;y1[i]+=10000;y2[i]+=10000;        }        ans=0;        for(i=1;i<=n;i++)        {            line[i*2-1].l=x1[i]+1;line[i*2-1].r=x2[i];line[i*2-1].f=1;line[i*2-1].h=y1[i];            line[i*2].l=x1[i]+1;line[i*2].r=x2[i];line[i*2].f=-1;line[i*2].h=y2[i];        }        sort(line+1,line+1+n*2,cmp);        solve();        for(i=1;i<=n;i++)        {            line[i*2-1].l=y1[i]+1;line[i*2-1].r=y2[i];line[i*2-1].f=1;line[i*2-1].h=x1[i];            line[i*2].l=y1[i]+1;line[i*2].r=y2[i];line[i*2].f=-1;line[i*2].h=x2[i];        }        sort(line+1,line+1+n*2,cmp);        solve();        printf("%d\n",ans);    }}



0 0
原创粉丝点击