poj1177 Picture 扫描线求矩形周长并
2015-11-05 22:09
423 查看
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.
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
Sample Output
#include<iostream>
#include<cstring>
#include<cstdio>
#include<ostream>
#include<istream>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define fi first
#define se second
#define ll long long
#define pii pair<int,int>
#define inf (1<<30)
#define eps 1e-8
#define pb push_back
using namespace std;
const int maxn=10010;
struct Line
{
int x,y1,y2;
int flag;
}line[maxn];
int y[maxn];
struct Node
{
int cover,num,len;
bool lf,rf;
}node[maxn<<2];
int n;
bool cmp(const Line& a,const Line& b)
{
return a.x<b.x;
}
void build(int l,int r,int rt)
{
node[rt].cover=node[rt].num=node[rt].len=node[rt].lf=node[rt].rf=0;
if(l+1==r) return;
build(l,(l+r)>>1,rt<<1);
build((l+r)>>1,r,rt<<1|1);
}
void pushUp(int l,int r,int rt)
{
if(node[rt].cover) {
node[rt].num=1;
node[rt].len=y[r]-y[l];
node[rt].lf=node[rt].rf=1;
}
else if(l+1==r) {
node[rt].num=node[rt].len=node[rt].lf=node[rt].rf=0;
}
else {
node[rt].num=node[rt<<1].num+node[rt<<1|1].num-(node[rt<<1].rf&&node[rt<<1|1].lf);
node[rt].len=node[rt<<1].len+node[rt<<1|1].len;
node[rt].lf=node[rt<<1].lf;
node[rt].rf=node[rt<<1|1].rf;
}
}
void update(int L,int R,int flag,int l,int r,int rt)
{
if(L<=l&&R>=r) {
node[rt].cover+=flag;
pushUp(l,r,rt);
}
if(l+1==r) return;
int m=((l+r)>>1);
if(L<=m)
update(L,R,flag,l,m,rt<<1);
if(R>=m)
update(L,R,flag,m,r,rt<<1|1);
pushUp(l,r,rt);
}
int main()
{
int x1,x2,y1,y2;
while(~scanf("%d",&n)) {
for(int i=0;i<n;i++) {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
line[i*2].x=x1;
line[i*2].y1=y1;
line[i*2].y2=y2;
line[i*2].flag=1;
line[i*2+1].x=x2;
line[i*2+1].y1=y1;
line[i*2+1].y2=y2;
line[i*2+1].flag=-1;
y[i*2]=y1; y[i*2+1]=y2;
}
sort(y,y+n*2);
int k=unique(y,y+n*2)-y;
sort(line,line+n*2,cmp);
build(0,k-1,1);
int ans=0;
int tot=n*2;
int pre=0;
for(int i=0;i<tot-1;i++) {
int L=lower_bound(y,y+k,line[i].y1)-y;
int R=lower_bound(y,y+k,line[i].y2)-y;
update(L,R,line[i].flag,0,k-1,1);
ans+=abs(node[1].len-pre)+node[1].num*2*(line[i+1].x-line[i].x);
pre=node[1].len;
}
ans+=pre;
printf("%d\n",ans);
}
return 0;
}
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.
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
#include<iostream>
#include<cstring>
#include<cstdio>
#include<ostream>
#include<istream>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define fi first
#define se second
#define ll long long
#define pii pair<int,int>
#define inf (1<<30)
#define eps 1e-8
#define pb push_back
using namespace std;
const int maxn=10010;
struct Line
{
int x,y1,y2;
int flag;
}line[maxn];
int y[maxn];
struct Node
{
int cover,num,len;
bool lf,rf;
}node[maxn<<2];
int n;
bool cmp(const Line& a,const Line& b)
{
return a.x<b.x;
}
void build(int l,int r,int rt)
{
node[rt].cover=node[rt].num=node[rt].len=node[rt].lf=node[rt].rf=0;
if(l+1==r) return;
build(l,(l+r)>>1,rt<<1);
build((l+r)>>1,r,rt<<1|1);
}
void pushUp(int l,int r,int rt)
{
if(node[rt].cover) {
node[rt].num=1;
node[rt].len=y[r]-y[l];
node[rt].lf=node[rt].rf=1;
}
else if(l+1==r) {
node[rt].num=node[rt].len=node[rt].lf=node[rt].rf=0;
}
else {
node[rt].num=node[rt<<1].num+node[rt<<1|1].num-(node[rt<<1].rf&&node[rt<<1|1].lf);
node[rt].len=node[rt<<1].len+node[rt<<1|1].len;
node[rt].lf=node[rt<<1].lf;
node[rt].rf=node[rt<<1|1].rf;
}
}
void update(int L,int R,int flag,int l,int r,int rt)
{
if(L<=l&&R>=r) {
node[rt].cover+=flag;
pushUp(l,r,rt);
}
if(l+1==r) return;
int m=((l+r)>>1);
if(L<=m)
update(L,R,flag,l,m,rt<<1);
if(R>=m)
update(L,R,flag,m,r,rt<<1|1);
pushUp(l,r,rt);
}
int main()
{
int x1,x2,y1,y2;
while(~scanf("%d",&n)) {
for(int i=0;i<n;i++) {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
line[i*2].x=x1;
line[i*2].y1=y1;
line[i*2].y2=y2;
line[i*2].flag=1;
line[i*2+1].x=x2;
line[i*2+1].y1=y1;
line[i*2+1].y2=y2;
line[i*2+1].flag=-1;
y[i*2]=y1; y[i*2+1]=y2;
}
sort(y,y+n*2);
int k=unique(y,y+n*2)-y;
sort(line,line+n*2,cmp);
build(0,k-1,1);
int ans=0;
int tot=n*2;
int pre=0;
for(int i=0;i<tot-1;i++) {
int L=lower_bound(y,y+k,line[i].y1)-y;
int R=lower_bound(y,y+k,line[i].y2)-y;
update(L,R,line[i].flag,0,k-1,1);
ans+=abs(node[1].len-pre)+node[1].num*2*(line[i+1].x-line[i].x);
pre=node[1].len;
}
ans+=pre;
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- 关于Jenkins Dynamic Parameter 的简单使用
- 大数据实时框架原理
- jump-game-ii
- XML简介
- hadoop 之 输出格式
- 控件属性clickable影响滑动手势响应问题
- 文法翻译
- for循环的类型以及while循环
- tableView-思路简介
- windows提取程序权限函数
- java掉用python
- Struts2中的I18N(国际化)处理
- 要做音频数据编程一些基础积累(MP3和WAV)
- HTML5
- Linux 下配置网卡的别名即网卡子IP的配置
- From feature descriptors to deep learning: 20 years of computer vision
- iOS隐私政策
- poj1765 November Rain 扫描线
- 全面解析Linux 内核 3.10.x - 抉择
- 【VMCloud云平台】私有云门户第一朵VM云(六)