Picture

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4475    Accepted Submission(s): 2207

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

 
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 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16
 
Sample Output
228

题目链接:HDU 1828

扫描线第三道题目,都是整数点且范围较小不需要离散化,主要学习了如何求轮廓线的周长(内周长+外周长),有两种方法这里用的是比较好写但是速度慢的一种——横着竖着各做一次扫描线,统计横竖的周长再求和输出,过程和求面积并类似,但是每一次累加的是覆盖长度的改变量即$abs(这一次更新之后的长度-上一次的长度)$,另外要注意一点就是当高度相同时要优先更新底边。

比如这样一组数据:

2

0 0 1 1

0 1 1 2

若不这样做会得到错误答案8,但其实边长只有4+2=6,原因就是错误地把中间的边也当作影响更新长度的情况了,实际是重叠之后两条边会一起抵消掉,刚开始写完debug半天最后发现是建树时没考虑范围要可能是负数……

代码:

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=2e4+7;
struct seg
{
int l,mid,r;
int len,cnt;
};
struct Line
{
int l,r,h,flag;
inline bool operator<(const Line &t)const
{
if(h==t.h)//若高度相等,则底边优先
return flag>t.flag;
return h<t.h;
}
};
seg T[N<<2];
Line xline[N],yline[N]; inline void pushup(int k)
{
if(T[k].cnt)
T[k].len=T[k].r-T[k].l+1;
else
{
if(T[k].l==T[k].r)
T[k].len=0;
else
T[k].len=T[LC(k)].len+T[RC(k)].len;
}
}
void build(int k,int l,int r)
{
T[k].l=l;
T[k].r=r;
T[k].mid=MID(l,r);
T[k].cnt=0;
T[k].len=0;
if(l==r)
return ;
build(LC(k),l,T[k].mid);
build(RC(k),T[k].mid+1,r);
}
void update(int k,int l,int r,int flag)
{
if(l<=T[k].l&&T[k].r<=r)
{
T[k].cnt+=flag;
pushup(k);
}
else
{
if(r<=T[k].mid)
update(LC(k),l,r,flag);
else if(l>T[k].mid)
update(RC(k),l,r,flag);
else
update(LC(k),l,T[k].mid,flag),update(RC(k),T[k].mid+1,r,flag);
pushup(k);
}
}
int main(void)
{
int n,i;
int xa,xb,ya,yb;
int ans,last;
while (~scanf("%d",&n))
{
int cnt=0;
int xR=-INF;
int yR=-INF;
int xL=INF;
int yL=INF;
for (i=0; i<n; ++i)
{
scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
xline[cnt]=(Line){xa,xb,ya,1};
yline[cnt++]=(Line){ya,yb,xa,1};//
xline[cnt]=(Line){xa,xb,yb,-1};
yline[cnt++]=(Line){ya,yb,xb,-1};//
if(xa>xR) xR=xa;
if(xa<xL) xL=xa;
if(xb>xR) xR=xb;
if(xb<xL) xL=xb; if(ya>yR) yR=ya;
if(ya<yL) yL=ya;
if(yb>yR) yR=yb;
if(yb<yL) yL=yb;
}
ans=0;
sort(xline,xline+cnt);
sort(yline,yline+cnt); last=0;
build(1,xL,xR);
for (i=0; i<cnt; ++i)
{
update(1,xline[i].l,xline[i].r-1,xline[i].flag);
ans=ans+abs(T[1].len-last);
last=T[1].len;
} last=0;
build(1,yL,yR);
for (i=0; i<cnt; ++i)
{
update(1,yline[i].l,yline[i].r-1,yline[i].flag);
ans=ans+abs(T[1].len-last);
last=T[1].len;
} printf("%d\n",ans);
}
return 0;
}

HDU 1828 Picture(线段树扫描线求周长)的更多相关文章

  1. HDU 1828 Picture (线段树+扫描线)(周长并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 给你n个矩形,让你求出总的周长. 类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y ...

  2. HDU 1828 Picture (线段树:扫描线周长)

    依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖 ...

  3. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

  4. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

  5. poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)

    题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...

  6. hdu 1828 Picture(线段树 || 普通hash标记)

    http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others)    Mem ...

  7. hdu 1828 Picture(线段树轮廓线)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. hdu 1542(线段树+扫描线 求矩形相交面积)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  9. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

随机推荐

  1. SQL 最基本使用

    --创建表 CREATE TABLE TreeData (id INT IDENTITY(1,1) PRIMARY KEY , pid INT ) --为表添加列 ALTER TABLE treeda ...

  2. D7控件\dw_cd_VirtualTreeview_v4.5.2\Demos\Advanced---TVirtualStringTree用法

    VST1: TVirtualStringTree; //按钮公用函数,根据不同 标签tag区分, Screen.Cursor := crHourGlass; //设置屏幕鼠标的形状为crhourGla ...

  3. BSGS[bzoj2242][bzoj3122]

    数论题. 操作一:直接快速幂就好了. 操作二:我用了exgcd,shy和lyz都喜欢欧拉函数...QAQ最后这块还写错了. 对于ax+by=gcd(a,b)的形式,我们可以把他们变成y'x+p'y=1 ...

  4. [bzoj4424]Fairy

    很久之前想写这题.结果还是把握不住CF的E,太神了啊....... 首先考虑的是二分图的性质,这个so easy,图中不存在奇数环. 然后分三种情况考虑: 1.只有一个奇数环,随便删除哪条 2.多个奇 ...

  5. 模拟 Codeforces Round #288 (Div. 2) A. Pasha and Pixels

    题目传送门 /* 模拟水题:给定n*m的空白方格,k次涂色,将(x,y)处的涂成黑色,判断第几次能形成2*2的黑色方格,若不能,输出0 很挫的判断四个方向是否OK */ #include <cs ...

  6. HTML元素的offsetWidht、clientWidth、scrollWidth属性区别

    每个HTML元素都有以下属性 offsetWidth:内容+内边距(padding)+边框+滚动条宽度,以css像素返回它的屏幕尺寸. offsetHeight:(同上) offsetLeft:如果o ...

  7. HTML无序列表和有序列表

    html无序列表<ul><li></li></ul>   ul属性设定:<ul type="square"> 常用属性值 ...

  8. c# 基本值类型及其默认值

    //值类型 C# 类型      .NET Framework 类型 bool            System.Boolean 4Byte 32bit布尔型变量 逻辑值,true或者false,默 ...

  9. CF#335 Board Game

    Board Game time limit per test 2.5 seconds memory limit per test 256 megabytes input standard input ...

  10. over

    overflow内容溢出要用到: scroll(内容溢出,出现滚动条) auto(自动适应) hidden(超出隐藏) overflow-y:scroll: 沿着y轴出现滚动条: overflow-x ...