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 ...
随机推荐
- API的理解和使用——哈希类型的命令
哈希常用的命令复习 命令 功能 hset key field value 设置哈希值 hsetnx 设置哈希值,field或键必须不存在 hget 获取某个file对应的值 hdel 删除一个或多个f ...
- 细说后端模板渲染、客户端渲染、node 中间层、服务器端渲染(ssr)
细说后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr) 前端与后端渲染方式的发展大致经历了这样几个阶段:后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr). 1. 后端 ...
- Mac OS访问Windows共享文件夹
原文地址:http://blog.csdn.net/jinhill/article/details/7246922 最近开始研究Mac OS,遇到的第一个问题就是如何在Mac OS中访问Windows ...
- React之jsx语法特性
jsx 语法,直接可以在js中使用html标签. 还可以通过花括号的形式,在html标签中,写js表达式. <div> { 1 + 2 } hello,world! </div> ...
- 时间序列数据库概览——基于文件(RRD)、K/V数据库(influxDB)、关系型数据库
一般人们谈论时间序列数据库的时候指代的就是这一类存储.按照底层技术不同可以划分为三类. 直接基于文件的简单存储:RRD Tool,Graphite Whisper.这类工具附属于监控告警工具,底层没有 ...
- [原创]Java动态生成word文档(图文并茂)
很多情况下,软件开发者需要从数据库读取数据,然后将数据动态填充到手工预先准备好的Word模板文档里,这对于大批量生成拥有相同格式排版的正式文件非常有用,这个功能应用PageOffice的基本动态填充功 ...
- codeforces 659G G. Fence Divercity(dp)
题目链接: G. Fence Divercity time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- ambari 维护模式及reset API 操作
Ambari 的维护模式(Maintenance Mode)介绍 Ambari 提供的 Maintenance Mode,是为了让用户在调试或者维护 Service 的时候,抑制不必要的告警(Aler ...
- 媒体格式分析之flv -- 基于FFMPEG
本来是应该先写一个媒体文件格式的简单讲解的,还没来得及写,以后再写.今天就先根据ffmpeg的flv.c的flv_demux这个结构体来讲解一下当前比较流行的媒体格式flv. FLV 是FLASH V ...
- 洛谷P1474货币系统——背包方案计数
题目:https://www.luogu.org/problemnew/show/P1474 完全背包,注意方案计数的方法. 代码如下: #include<iostream> #inclu ...