【POJ1171】【线段树+扫描线】【矩形周长】【坑区间要分3类讨论】
来源:互联网 发布:汤灿到底怎么了 知乎 编辑:程序博客网 时间:2024/06/05 15:02
Language:
Picture
Time Limit: 2000MS Memory Limit: 10000KTotal Submissions: 11200 Accepted: 5915
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.
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.
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 2515 -4 24 140 -6 16 42 15 10 2230 10 36 2034 0 40 16
Sample Output
228
Source
IOI 1998
[Submit] [Go Back] [Status] [Discuss]
首先,周长是什么?
周长是线段的长度。 是哪些线段呢? 投影下来的线段。 那么投影下来的线段在原矩形的什么位置呢。 投影下来的线段 一定是在原矩形的4边上。
用2根 平行于x轴的直线进行扫描, 然后再沿着y轴方向进行投影。 如果一根线段(X1,X2,Y)被覆盖了,那么一定存在一边yi < Y, 存在另外一边yj > Y。所以自下往上,第一次投影下来(沿着y轴投影)的位置一定是周长, 然后第二次的如果落在了 第一次投影的线段中,那么我们知道 重叠的不能计算。 那么第二次的全部投影长度-第一次的全部投影长度就是新增的横向的投影周长。 纵向的 一根的长度很好知道, 那么有多少根呢? 其实就是染色区间的数量。 坑点就是 区间要分三类讨论。。。
#include <iostream>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <string>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;#define rep(i,a,n) for (int i=a;i<n;i++)#define per(i,a,n) for (int i=n-1;i>=a;i--)#define mp push_back#define lson l,m,rt<<1#define rson m,r,rt<<1|1struct Line{int l,r,y,s;Line() {};Line(int ll,int rr,int yy,int ss):l(ll),r(rr),y(yy),s(ss){};}line[10010];int X[10010];int color[10010*4];int numseg[10010*4];int len[10010*4];bool lbd[10010*4],rbd[10010*4];int cmp(Line a,Line b){return a.y < b.y;}int n;int t;void build(int l,int r,int rt){lbd[rt] = rbd[rt] = 0;len[rt] = 0;numseg[rt] = 0;color[rt] = 0;if(r - l == 1) return ;int m = (l + r) >> 1;build(lson);build(rson);}void PushUp(int rt,int l,int r){if(color[rt] > 0){lbd[rt] = rbd[rt] = true;len[rt] = X[r] - X[l];numseg[rt] = 1;return ;}if(r - l == 1){lbd[rt] = rbd[rt] = false;len[rt] = 0;numseg[rt] = 0;}else{lbd[rt] = lbd[rt<<1];rbd[rt] = rbd[rt<<1|1];numseg[rt] = numseg[rt<<1] + numseg[rt<<1|1];if(rbd[rt<<1] && lbd[rt<<1|1]){numseg[rt] -= 1;}len[rt] = len[rt<<1] + len[rt<<1|1];}}void update(int L,int R,int add,int l,int r,int rt){if(L == X[l] && R == X[r]){color[rt] += add;PushUp(rt,l,r);return ;}int m = (l + r) >> 1;if(L <= X[m-1]) update(L,min(R,X[m]),add,lson);if(X[m] <= R-1) update(max(L,X[m]),R,add,rson);PushUp(rt,l,r);}int main(){freopen("in.txt","r",stdin);while(scanf("%d",&n) != EOF){t = 0;for(int i=0;i<n;i++){int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);line[t] = Line(x1,x2,y1,1);X[t ++] = x1;line[t] = Line(x1,x2,y2,-1);X[t ++] = x2;}sort(line,line+t,cmp);sort(X,X+t);int MAXN = unique(X,X+t) - X;build(0,MAXN-1,1); int ans = 0;int pre = 0;for(int i=0;i<t-1;i++){update(line[i].l,line[i].r,line[i].s,0,MAXN-1,1);ans += abs(len[1] - pre);pre = len[1];ans += numseg[1] * 2 * (line[i+1].y - line[i].y);}update(line[t-1].l,line[t-1].r,line[t-1].s,0,MAXN-1,1);ans += abs(len[1] - pre);printf("%d\n",ans);}}
0 0
- 【POJ1171】【线段树+扫描线】【矩形周长】【坑区间要分3类讨论】
- hdu1828 Picture(扫描线+矩形周长并+线段树)
- hdu1828&poj1177(线段树求矩形交周长,扫描线)
- hdu1828 线段树扫描线求矩形面积的周长
- 【线段树 + 扫描线】poj 1177 pictures 矩形周长并
- 【poj1177】Picture(矩形周长并+线段树+扫描线)
- hdu1828 Picture(线段树+扫描线+矩形周长并)
- 矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
- 矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
- 线段树 矩形周长
- 线段树辅助——扫描线法计算矩形周长并(轮廓线)
- poj 1177 线段树+扫描线 求矩形交的周长
- hdu 1828、poj1177求矩形周长并 线段树 扫描线
- hdu 1828 Picture(线段树扫描线矩形周长并)
- poj 1177 线段树+离散化+扫描线 求矩形的周长和
- 【POJ】1171 求矩形并的周长(线段树+扫描线+离散化)
- poj-1177 Picture(矩形周长并,线段树+扫描线)
- poj1177[IOI1998]Picture (扫描线+离散化+线段树,求矩形周长并)
- UVA1347-Tour 双调欧几里得旅行商问题 - 递归记忆实现
- 设计模式面试
- 卸载ORACLE
- 强大的c#.net应用程序winform框架类库-WeifenLuo.WinFormsUI.Docking.dll
- C++三法则:如果需要析构函数,则一定需要拷贝构造函数和赋值操作符
- 【POJ1171】【线段树+扫描线】【矩形周长】【坑区间要分3类讨论】
- 短路和非短路的"与"、"或"
- SWIFT 2.0 复习笔记
- mysql 修改server characterset latin1为 utf8(乱码问题)
- jenkins 如何做到触发远程构建
- iOS开发UI篇—transframe属性(形变)
- STAF FS COPY FILE
- Android 之调试
- [转载]eclipse构建maven项目