Picture poj1177
Picture
| Time Limit: 2000MS | Memory Limit: 10000K | |
| Total Submissions: 12265 | Accepted: 6484 |
Description
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
0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.
Output
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
#include <stdio.h>
#include <algorithm>
#define LEN 10000
using namespace std; struct Node
{
int left;
int right;
int count;//被覆盖次数
int line;//所包含的区间数量
int lbd;//左端点是否被覆盖
int rbd;//右端点是否被覆盖
int m;//测度,即覆盖的区间长度,如[2,8]就为6
}; struct ScanLine
{
int x;//横坐标
int y1;//扫描线的下端点
int y2;//扫描线的上端点
int flag;//若该扫描线属于矩形的左边的竖边,
//如AB,则叫做入边,值为1,若属于矩形的右边的竖边,如CD,则叫做出边,值为0
}; struct Node node[LEN*];
struct ScanLine scan[LEN];
int y[LEN]; void build(int l, int r, int i)
{
node[i].left = l;
node[i].right = r;
node[i].count = ;
node[i].m = ;
node[i].line = ;
if (r - l > )
{
int middle = (l + r)/;
build(l, middle, *i + );
build(middle, r, *i + );
}
} //更新测度m
void update_m(int i)
{
if (node[i].count > )
node[i].m = y[node[i].right] - y[node[i].left];
else if (node[i].right - node[i].left == )
node[i].m = ;
else
{
node[i].m = node[*i + ].m + node[*i + ].m;
}
} //更新line
void update_line(int i)
{
if (node[i].count > )
{
node[i].lbd = ;
node[i].rbd = ;
node[i].line = ;
}
else if (node[i].right - node[i].left == )
{
node[i].lbd = ;
node[i].rbd = ;
node[i].line = ;
}
else
{
node[i].lbd = node[*i + ].lbd;
node[i].rbd = node[*i + ].rbd;
node[i].line = node[*i + ].line + node[*i + ].line
- node[*i + ].rbd*node[*i + ].lbd;
}
} void insert(int l, int r, int i)//l和r分别是这条扫描线的下端点和上端点的纵坐标
//相当于区间修改
{
//在这里要取离散化之前的原值进行比较
if (y[node[i].left] >= l && y[node[i].right] <= r)
//如果这个区间内最下的点的纵坐标大于insert扫描线的上端点的纵坐标
//且这个区间内最上的点的纵坐标小于insert扫描线的下端点的纵坐标
(node[i].count)++;//这个区间包含于这条线段,一定覆盖了这个区间内的扫描线
else if (node[i].right - node[i].left == )return;//因为坐标都是整数
else
{
int middle = (node[i].left + node[i].right)/;
if (r <= y[middle])//这条扫描线完全包含于这个区间的中点到最下
insert(l, r, *i + );
else if (l >= y[middle])//完全包含于这个区间的最上到中点
insert(l, r, *i + );
else//穿过中点
{
insert(l, y[middle], *i + );
insert(y[middle], r, *i + );
}
}
update_m(i);
update_line(i);
} void remove(int l, int r, int i)
{
//在这里要取离散化之前的原值进行比较
if (y[node[i].left] >= l && y[node[i].right] <= r)
(node[i].count)--;//完全被包含就删去这条边
else if (node[i].right - node[i].left == )
return;
else
{
int middle = (node[i].left + node[i].right)/;
if (r <= y[middle])
remove(l, r, *i + );
else if (l >= y[middle])
remove(l, r, *i + );
else
{
remove(l, y[middle], *i + );
remove(y[middle], r, *i + );
}
}
update_m(i);
update_line(i);
} bool cmp(struct ScanLine line1, struct ScanLine line2)
{
if (line1.x == line2.x)
return line1.flag > line2.flag;
return (line1.x < line2.x);
} int main()
{
int n;
scanf("%d", &n);//输入有几个矩形
int x1, y1, x2, y2;
int i = ;
while (n--)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);//(x1,y1)左下,(x2,y2)右上
scan[i].x = x1;//加扫描线
scan[i].y1 = y1;
scan[i].y2 = y2;
scan[i].flag = ;
y[i++] = y1;//y[]记录所有点的纵坐标
scan[i].x = x2;
scan[i].y1 = y1;
scan[i].y2 = y2;
scan[i].flag = ;
y[i++] = y2;
}
sort(y, y + i);//所有纵坐标从下到上排序
sort(scan, scan + i, cmp);//所有扫描线从左到右排序
int unique_count = unique(y, y + i) - y;//y数组中不重复的个数
build(, unique_count - , );//离散化,建立线段树 int perimeter = ;
int now_m = ;
int now_line = ; for (int j = ; j < i; j++)//枚举每条扫描线
{
if (scan[j].flag)//如果是左边
insert(scan[j].y1, scan[j].y2, );
else//如果是右边
remove(scan[j].y1, scan[j].y2, );
if (j >= )
perimeter += *now_line*(scan[j].x - scan[j-].x);
perimeter += abs(node[].m - now_m);
now_m = node[].m;
now_line = node[].line;
} printf("%d\n", perimeter);
return ;
}
Picture poj1177的更多相关文章
- [POJ1177]Picture
[POJ1177]Picture 试题描述 A number of rectangular posters, photographs and other pictures of the same sh ...
- 【poj1177】 Picture
http://poj.org/problem?id=1177 (题目链接) 题意 求矩形周长并. Solution 转自:http://www.cnblogs.com/Booble/archive/2 ...
- poj1177 Picture 矩形周长并
地址:http://poj.org/problem?id=1177 题目: Picture Time Limit: 2000MS Memory Limit: 10000K Total Submis ...
- 【HDOJ1828&&POJ1177】Picture(线段树,扫描线)
题意:给定n个矩形,求他们的并的周长 n<=5e3,abs(x[i])<=1e4 思路:From https://www.cnblogs.com/kuangbin/archive/2013 ...
- POJ1177 Picture —— 求矩形并的周长 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/POJ-1177 A number of rectangular posters, photographs and other pict ...
- CQOI2005 三角形面积并 和 POJ1177 Picture
1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1664 Solved: 443[Submit][Stat ...
- POJ1177 Picture 线段树+离散化+扫描线
求最终的覆盖图形周长,写这种代码应该短而精确,差的比较远 /* Problem: 1177 User: 96655 Memory: 348K Time: 32MS Language: C++ Resu ...
- POJ-1177 Picture 矩形覆盖周长并
题目链接:http://poj.org/problem?id=1177 比矩形面积并麻烦点,需要更新竖边的条数(平行于x轴扫描)..求横边的时候,保存上一个结果,加上当前长度与上一个结果差的绝对值就行 ...
- IOI1998 hdu1828 poj1177 Picture
写了一发扫描线竟然狂WA不止,hdu死活过不了,poj和当时IOI的数据(还花了我1dsdn积分..)都过了. 然后看到谋篇blog里有评论,把数据拿下来发现WA了. 数据是 20 0 1 11 0 ...
随机推荐
- Oracle | PL/SQL Check约束用法详解
1. 目标 实例讲解在Oracle中如何使用CHECK约束(创建.启用.禁用和删除) 2. 什么是Check约束? CHECK约束指在表的列中增加额外的限制条件. 注: CHECK约束不能在VIEW中 ...
- re.sub用法
re.sub功能是对于一个输入的字符串,利用正则表达式,来实现字符串替换处理的功能返回处理后的字符串 re.sub共有五个参数 三个必选参数pattern,repl,string 两个可选参数coun ...
- P4474 王者之剑
P4474 王者之剑 题目大意 n*m的带权网格,任意选择起点开始时刻为0秒.以下操作,每秒按顺序执行 在第i秒开始的时候,在方格(x,y)上,获得(x,y)的值 在偶数秒,周围四格的值清零 每秒可选 ...
- 【字符串题目】poj 3096 Surprising Strings
Surprising Strings Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6193 Accepted: 403 ...
- FZU1989 AntiAC —— 字符串
题目链接:https://vjudge.net/problem/FZU-1989 Problem 1989 AntiAC Accept: 79 Submit: 399Time Limit: 4 ...
- LVS与Keepalived
lvs与Nginx区别 LVS的负载能力强,因为其工作方式逻辑非常简单,仅进行请求分发,而且工作在网络的第4层,没有流量,所以其效率不需要有过多的忧虑. LVS基本能支持所有应用,因为工作在第4层,所 ...
- zabbix haproxy 监控
摘自: http://www.tuicool.com/articles/JrYNNrm 写的非常好,步步紧逼,环环相扣.直到成功! 文章首发站点:OpensGalaxy 这是一个HAProxy的zab ...
- 本地Ubuntu16搭建Seafile
本地搭建Seafile 1.下载 2.解压 3.创建目录 mySeafile 4.将解压包放入mySeafile中 5.创建installed 将压缩包放入installed 安装准备工作 pytho ...
- 分享知识-快乐自己:Hibernate对象的三种状态
图解: 1):瞬时状态(Transient) 对象与session没有关联,数据库中没有对应的数据. 一般new出来的对象便是瞬时对象. 对瞬时对象使用save()方法便使之成为持久对象. 由于数据库 ...
- IntelliJ IDEA 同时启动多个Tomcat实例端口是会冲突