【题目】

Picture

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
Source
 
 
【题意】
  看图就懂,求矩形周长并。
 
【分析】
  很容易想到x和y分开搞,其实就是线段的并咯,但是要注意他有退出的一刻。
  进去和退出都有可能影响答案,但是不影响答案就不需要加进去ans。
 
 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define Maxn 100010 struct hp
{
int x1,x2,flag;
double y;
}t[Maxn*];int tl;
struct lsh
{
double x;
int id;
}q[Maxn*];int ql; bool cmp(lsh x,lsh y) {return x.x<y.x;}
bool cmp2(hp x,hp y) {return (x.y==y.y)?(x.flag>y.flag):(x.y<y.y);} int mymin(int x,int y) {return x<y?x:y;} double dis[*Maxn]; struct node
{
int l,r,lc,rc,cnt;
double sm;
}tr[Maxn*];int len;
int build(int l,int r)
{
int x=++len;
tr[x].l=l;tr[x].r=r;
tr[x].sm=tr[x].cnt=;
if(l<r-)
{
int mid=(tr[x].l+tr[x].r)>>;
tr[x].lc=build(l,mid);
tr[x].rc=build(mid,r);
}
else tr[x].lc=tr[x].rc=;
return x;
} void upd(int x)
{
int l=tr[x].l,r=tr[x].r,lc=tr[x].lc,rc=tr[x].rc;
if(tr[x].cnt>=) tr[x].sm=dis[r]-dis[l];
else tr[x].sm=tr[lc].sm+tr[rc].sm;
} void change(int x,int l,int r,int c)
{
if(tr[x].l==l&&tr[x].r==r)
{
tr[x].cnt+=c;
upd(x);
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if(r<=mid) change(tr[x].lc,l,r,c);
else if(l>=mid) change(tr[x].rc,l,r,c);
else
{
change(tr[x].lc,l,mid,c);
change(tr[x].rc,mid,r,c);
}
upd(x);
} double x1[Maxn],ya[Maxn],x2[Maxn],y2[Maxn];
int n;
void init()
{
for(int i=;i<=n;i++) scanf("%lf%lf%lf%lf",&x1[i],&ya[i],&x2[i],&y2[i]);
} double ans; void ffind()
{
tl=;ql=;
for(int i=;i<=n;i++)
{
//t[++tl].x1,
t[++tl].flag=;t[tl].y=ya[i];
t[++tl].flag=-;t[tl].y=y2[i];
q[++ql].x=x1[i],q[ql].id=tl;
q[++ql].x=x2[i],q[ql].id=tl+*n;
}
sort(q+,q++ql,cmp);
int p=;
for(int i=;i<=ql;i++)
{
if(q[i].x!=q[i-].x||p==) p++,dis[p]=dis[p-]+q[i].x-q[i-].x;
if(q[i].id<=*n) t[q[i].id].x1=t[q[i].id-].x1=p;
else t[q[i].id-*n].x2=t[q[i].id--*n].x2=p;
}
sort(t+,t++tl,cmp2);
len=;tr[].sm=;
build(,p);
double now=;
for(int i=;i<=tl;i++)
{
change(,t[i].x1,t[i].x2,t[i].flag);
double nn=tr[].sm;
if(t[i].flag==) ans+=nn-now;
else ans+=now-nn;
now=nn;
}
} int main()
{
int T;
// scanf("%d",&T);
// T=1;
while(scanf("%d",&n)!=EOF)
{ init();
ans=;
ffind();
// printf("%.0lf\n",ans);
for(int i=;i<=n;i++)
{
double tt;
tt=x1[i],x1[i]=ya[i],ya[i]=tt;
tt=x2[i],x2[i]=y2[i],y2[i]=tt;
}
ffind();
printf("%.0lf\n",ans);
}
return ;
}

ws的题目,谁说了多组啊!!!

哦,对了,有一个比较坑的地方【ORZ。。GDXB

矩形边界重合的时候的处理。举个例子,在处理x轴的时候:

中间那条一次也不算。

这个东西,在排序的时候注意一下就好了。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define Maxn 100010 struct hp
{
int x1,x2,flag;
double y;
}t[Maxn*];int tl;
struct lsh
{
double x;
int id;
}q[Maxn*];int ql; bool cmp(lsh x,lsh y) {return x.x<y.x;}
bool cmp2(hp x,hp y) {return (x.y==y.y)?(x.flag>y.flag):(x.y<y.y);} int mymin(int x,int y) {return x<y?x:y;} double dis[*Maxn]; struct node
{
int l,r,lc,rc,cnt;
double sm;
}tr[Maxn*];int len;
int build(int l,int r)
{
int x=++len;
tr[x].l=l;tr[x].r=r;
tr[x].sm=tr[x].cnt=;
if(l<r-)
{
int mid=(tr[x].l+tr[x].r)>>;
tr[x].lc=build(l,mid);
tr[x].rc=build(mid,r);
}
else tr[x].lc=tr[x].rc=;
return x;
} void upd(int x)
{
int l=tr[x].l,r=tr[x].r,lc=tr[x].lc,rc=tr[x].rc;
if(tr[x].cnt>=) tr[x].sm=dis[r]-dis[l];
else tr[x].sm=tr[lc].sm+tr[rc].sm;
} void change(int x,int l,int r,int c)
{
if(tr[x].l==l&&tr[x].r==r)
{
tr[x].cnt+=c;
upd(x);
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if(r<=mid) change(tr[x].lc,l,r,c);
else if(l>=mid) change(tr[x].rc,l,r,c);
else
{
change(tr[x].lc,l,mid,c);
change(tr[x].rc,mid,r,c);
}
upd(x);
} double x1[Maxn],ya[Maxn],x2[Maxn],y2[Maxn];
int n;
void init()
{
for(int i=;i<=n;i++) scanf("%lf%lf%lf%lf",&x1[i],&ya[i],&x2[i],&y2[i]);
} double ans; void ffind()
{
tl=;ql=;
for(int i=;i<=n;i++)
{
//t[++tl].x1,
t[++tl].flag=;t[tl].y=ya[i];
t[++tl].flag=-;t[tl].y=y2[i];
q[++ql].x=x1[i],q[ql].id=tl;
q[++ql].x=x2[i],q[ql].id=tl+*n;
}
sort(q+,q++ql,cmp);
int p=;
for(int i=;i<=ql;i++)
{
if(q[i].x!=q[i-].x||p==) p++,dis[p]=dis[p-]+q[i].x-q[i-].x;
if(q[i].id<=*n) t[q[i].id].x1=t[q[i].id-].x1=p;
else t[q[i].id-*n].x2=t[q[i].id--*n].x2=p;
}
sort(t+,t++tl,cmp2);
len=;tr[].sm=;
build(,p);
double now=;
for(int i=;i<=tl;i++)
{
change(,t[i].x1,t[i].x2,t[i].flag);
double nn=tr[].sm;
if(t[i].flag==) ans+=nn-now;
else ans+=now-nn;
now=nn;
}
} int main()
{
int T;
// scanf("%d",&T);
// T=1;
while(scanf("%d",&n)!=EOF)
{ init();
ans=;
ffind();
// printf("%.0lf\n",ans);
for(int i=;i<=n;i++)
{
double tt;
tt=x1[i],x1[i]=ya[i],ya[i]=tt;
tt=x2[i],x2[i]=y2[i],y2[i]=tt;
}
ffind();
printf("%.0lf\n",ans);
}
return ;
}

2016-11-10 15:49:48

【HDU 1828】 Picture (矩阵周长并,线段树,扫描法)的更多相关文章

  1. HDU 1828 Picture(长方形的周长和)

    HDU 1828 Picture 题目链接 题意:给定n个矩形,输出矩形周长并 思路:利用线段树去维护,分别从4个方向扫一次,每次多一段的时候,就查询该段未被覆盖的区间长度,然后周长就加上这个长度,4 ...

  2. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  3. HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模

    Multiply game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  4. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  5. 51nod 1206 && hdu 1828 Picture (扫描线+离散化+线段树 矩阵周长并)

    1206 Picture  题目来源: IOI 1998 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 给出平面上的N个矩形(矩形的边平行于X轴 ...

  6. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  7. HDU 1828 Picture(线段树扫描线求周长)

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

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

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

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

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

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

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

随机推荐

  1. javascript进击(四)HTML DOM

    HTML DOM (文档对象模型) 什么是DOM? DOM 是 W3C(万维网联盟)的标准. DOM 定义了访问 HTML 和 XML 文档的标准. W3C 文档对象模型 (DOM) 是中立于平台和语 ...

  2. sql快速生成大量数据

    先插入一条数据 insert into table(a,b,c,d) values(1,2,3,4) 然后重复执行以下sql语句 没执行一次 数据就会倍增 insert into table(a,b, ...

  3. css placeholder 颜色设置

    因为每个浏览器的CSS选择器都有所差异,所以需要针对每个浏览器做单独的设定(可以在冒号前面写input和textarea). ::-webkit-input-placeholder { /* WebK ...

  4. 首页TAB页的技术选择与功能实现

    一般的选择是用viewpager,这个有开源库.不过因为要引入开源库,所以有时候显得比较大. 下面这段代码是用在一个BaseActivity上面的,下面继承的Activity直接使用该方法,就可以完成 ...

  5. mvc Routing特性优化

    在mvc中,Url地址是利用routing特性来支持,但是这个Routing有个问题,多个不同的地址和指向同一个action方法, 例如: http://test.com (默认) http://te ...

  6. MVC小系列(二)【Razor 模板引擎】

    Razor 模板引擎 Razor模板页:它使我们不用再使用master模板了 一 :@Url.Content:是可以加载CSS和JS等文件比如: <link href="@Url.Co ...

  7. 自动构建工具Ant的使用-笔记

    第一:什么是Ant? Apache Ant是一个基于Java的生成工具.据最初的创始人James Duncan Davidson的介绍,这个工具的名称是another neat tool(另一个整洁的 ...

  8. onMouseDown onMouseUp onMouseMove(移动鼠标图像大小变化)

  9. Codevs 1217 借教室 2012年NOIP全国联赛提高组

    1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在大学期间,经常需要租借教 ...

  10. 第16章 网络IPC:套接字总结

    1 套接字是通信端点的抽象 创建套接字: int socket(int domain,int type,int protocol) domain:通信域 AF_INET.AF_INET6.AF_LOC ...