【49.23%】【hdu 1828】Picture
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4487 Accepted Submission(s): 2209
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
【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=1828
【题解】
线段树扫描线求矩形的并周长;
cnt域仍旧是记录这个区间内下边的长度比上边多的个数;
sumhx表示这个区间横线的长度;
sumsx表示这个区间内竖线的个数(去掉在内部的线,只保留不重复的);
lsx和rsx表示这个区间内的最左边和最右边是否有竖线(用于去掉内部的线);
从下往上扫描所有的下边和上边;(把所有的边处理处理按照高度排序;)
用竖线的个数乘两条线的高度差+横线的长度;
其中横线的长度要用当前整个区间的横线长度减去上一次整个区间的横线长度的绝对值值差来搞;
/*以下内容看完代码再看:
那个区间去掉重复的竖直线的;
可以用
1-3和3-5来体会;(横坐标)
即1-3和3-5是两个连在一起的的矩形;
但是竖线只算1和5,则中间那个3会被删掉->即-=2;(因为会插入两次所以得减2);
然后是那个排序的时候,相同高度的不能直接跳过;还要安装它们的上下边的属性来排;下边要先处理;
比如下图情况
*/
//上图如果先处理下边;那个△x会被多算一次;即直接增加了x(因为这个时候上边还没被处理;减last的时候会直接加上x而不是x-△x;
【完整代码】
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
using namespace std;
const int MAXN = 22000;
const int dx[5] = {0,1,-1,0,0};
const int dy[5] = {0,0,0,-1,1};
const double pi = acos(-1.0);
struct abc
{
int l,r,h,k;
};
int n,num = 0,cnt[MAXN<<2],sumhx[MAXN<<2],sumsx[MAXN<<2];
bool lsx[MAXN<<2],rsx[MAXN<<2];
abc a[MAXN];
bool cmp(abc a,abc b)
{
if (a.h==b.h)
return a.k>b.k;
return a.h < b.h;
}
void push_up(int rt,int l,int r)
{
if (cnt[rt])
{
lsx[rt]=rsx[rt] = 1;
sumhx[rt] = r-l+1;
sumsx[rt] = 2;
}
else
if (l==r)
lsx[rt]=rsx[rt]=sumhx[rt]=sumsx[rt] = 0;
else
{
sumhx[rt] = sumhx[rt<<1]+sumhx[rt<<1|1];
sumsx[rt] = sumsx[rt<<1]+sumsx[rt<<1|1];
lsx[rt] = lsx[rt<<1];
rsx[rt] = rsx[rt<<1|1];
if (rsx[rt<<1] && lsx[rt<<1|1])
sumsx[rt]-=2;
}
}
void up_data(int L,int R,int c,int l,int r,int rt)
{
if (L<=l && r<=R)
{
cnt[rt]+=c;
push_up(rt,l,r);
return;
}
int m = (l+r)>>1;
if (L<=m)
up_data(L,R,c,lson);
if (m < R)
up_data(L,R,c,rson);
push_up(rt,l,r);
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
while (~scanf("%d",&n))
{
memset(lsx,0,sizeof(lsx));
memset(rsx,0,sizeof(rsx));
memset(sumsx,0,sizeof(sumsx));
memset(sumhx,0,sizeof(sumhx));
memset(cnt,0,sizeof(cnt));
num = 0;
int tl = 10000,tr=-10000;
for (int i = 1;i <= n;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
a[++num].l = x1;a[num].r = x2;a[num].h = y1;a[num].k = 1;
a[++num].l = x1;a[num].r = x2;a[num].h = y2;a[num].k = -1;
tl = min(tl,x1);tr = max(tr,x2);
}
sort(a+1,a+1+num,cmp);
int last = 0,ans = 0;
for (int i = 1;i <= num;i++)
{
if (a[i].l<a[i].r)
up_data(a[i].l,a[i].r-1,a[i].k,tl,tr-1,1);
ans += sumsx[1]*(a[i+1].h-a[i].h);
ans += abs(sumhx[1]-last);
last = sumhx[1];
}
printf("%d\n",ans);
}
return 0;
}
【49.23%】【hdu 1828】Picture的更多相关文章
- 【HDU 1828】 Picture (矩阵周长并,线段树,扫描法)
[题目] Picture Problem Description A number of rectangular posters, photographs and other pictures of ...
- Picture【HDU - 1828】【扫描线】
题目链接 这道题求的是这些可能存在重叠的小方块可能构成的合成方块的周长的值是多少,有简单却会很复杂的做法就是去跑纵向和横向两次的扫描线,求得最后的两个周长和,但是这样的做法未免显得复杂了,我们完全可以 ...
- 【改革春风吹满地 HDU - 2036 】【计算几何-----利用叉积计算多边形的面积】
利用叉积计算多边形的面积 我们都知道计算三角形的面积时可以用两个邻边对应向量积(叉积)的绝对值的一半表示,那么同样,对于多边形,我们可以以多边形上的一个点为源点,作过该点并且过多边形其他点中的某一个的 ...
- HDU 1828:Picture(扫描线+线段树 矩形周长并)
题目链接 题意 给出n个矩形,求周长并. 思路 学了区间并,比较容易想到周长并. 我是对x方向和y方向分别做两次扫描线.应该记录一个pre变量,记录上一次扫描的时候的长度,对于每次遇到扫描线统计答案的 ...
- 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- 七夕节 (HDU - 1215) 【简单数论】【找因数】
七夕节 (HDU - 1215) [简单数论][找因数] 标签: 入门讲座题解 数论 题目描述 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们 ...
- 【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间 ...
- 【贪心】【模拟】HDU 5491 The Next (2015 ACM/ICPC Asia Regional Hefei Online)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5491 题目大意: 一个数D(0<=D<231),求比D大的第一个满足:二进制下1个个数在 ...
- 【动态规划】【二分】【最长上升子序列】HDU 5773 The All-purpose Zero
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5773 题目大意: T组数据,n个数(n<=100000),求最长上升子序列长度(0可以替代任何 ...
随机推荐
- 洛谷P2522 [HAOI2011]Problem b (莫比乌斯反演+容斥)
题意:求$\sum_{i=a}^{b}\sum_{j=c}^{d}[gcd(i,j)==k]$(1<=a,b,c,d,k<=50000). 是洛谷P3455 [POI2007]ZAP-Qu ...
- java连接oracle jdbc连接
Class.forName("oracle.jdbc.driver.OracleDriver"); Connection ct=Driver.Magager.getConnecti ...
- oracle表复杂查询--创建数据库实例
n 创建数据库有两种方法: 1)通过oracle提供的向导工具 2)我们可以用手工步骤直接创建 但我们创建完一个新的数据库实例后,在服务中就会有两个新的服务创建,这时,你根据实际需要去启动相应的数据 ...
- LinkedHashMap.get("key")
解析json串:得到的结果用LinkedHashMap存储,但是有个一个字段 data 的对应value是“”(json中)但是Map中get的不是空,而是value为“[]” LinkedHas ...
- 从零学React Native之02状态机
本篇文章首发于简书 欢迎关注 之前我们介绍了RN相关的知识: 是时候了解React Native了 从零学React Native之01创建第一个程序 本篇文章主要介绍下下面的知识: 1.简单界面的搭 ...
- OpenStack组件系列☞glance搭建
第一步:glance关于数据库的操作 mysql -u root -p #登入数据库 CREATE DATABASE glance; #新建库keystone GRANT ALL PRIVILEGES ...
- 手动实现如何从H264流中提取SPS/PPS信息
1,代码比较简单,可以直接用了.流的第一个NALU一定是SPS void get_sps_pps_nalu(uint8_t *data, int len, std::vector<uint8_t ...
- ubuntu 运行级别initlevel
Linux 系统任何时候都运行在一个指定的运行级上,并且不同的运行级的程序和服务都不同,所要完成的工作和要达到的目的都不同,系统可以在这些运行级之间进行切换,以完成不同的工作.Ubuntu 的系统运行 ...
- idea各种中文显示乱码解决大全
本文链接:https://blog.csdn.net/liqimo1799/article/details/81811153中文乱码问题分类: 编码普通中文乱码properties文件中文乱码cons ...
- CSS3 Box-shadow 阴影效果用法
一.基本用法: 二.内阴影用法: 三.阴影扩展长度值: box-shadow: 4rpx 4rpx 8rpx #aaa;