POJ 1177 线段树+扫描线
来源:互联网 发布:淘宝小产品拍摄技巧 编辑:程序博客网 时间:2024/06/17 20:32
题意
给一堆正方形,问组合图形周长
题解
首先可以做扫描线入门题HDU 1542。了解了扫描线的原理之后,这道题其实就非常简单了。尤其是POJ还没有判重边。
可以直接用最粗暴的方式,横向扫描一次,纵向扫描一次。每次扫描,判断相比上一次宽度(长度)变化了多少,周长就加多少。扫描两次以后,周长即为所求。
注意事项
有个地方感觉很玄学,但是也很重要。离散化数组要开4倍,目前还尚不清楚原因,ORZ。。。
另外的话,HDU1828与这道题相同,但是HDU1828存在重边的情况。关于重合边,只要在排序的时候特殊处理一下就可以了。将入边排在前面,出边排在后面,就不会出现重复计算的问题了。
代码
#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#include<stack>#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define INF 0x3f3f3f3f3f3f3f3f#define LL long long#define MAXN 10010#define SIZE 95#define EPS 1e-10#define MOD 1000000007using namespace std;struct Node { int x1,x2,y1,y2; int low; Node() {} Node(int x1,int y1,int x2,int y2,int low):x1(x1),y1(y1),x2(x2),y2(y2),low(low) {} bool operator < (const Node b) const { if(x1==b.x1){ return low>b.low; } return x1<b.x1; }};Node nodes[MAXN<<1],nodes2[MAXN<<1];int y[MAXN<<2],x[MAXN<<2];int num[MAXN<<2],add[MAXN<<2];int lt,rt,v;void maintain(int o,int l,int r){ if(add[o]>0){ num[o]=y[r]-y[l-1]; }else if(l==r){ num[o]=0; }else{ num[o]=num[o*2]+num[o*2+1]; }}void update(int o,int l,int r) { if(lt<=l&&rt>=r) { add[o]+=v; } else { int m=l+(r-l)/2; if(lt<=m) { update(o*2,l,m); } if(rt>m) { update(o*2+1,m+1,r); } } maintain(o,l,r);}int main() { int n; W(~scanf("%d",&n)) { MEM(num,0); MEM(add,0); int m=0; UP(i,0,n) { int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); y[m]=y1,y[m+1]=y2; x[m]=x1,x[m+1]=x2; nodes2[m]=Node(y1,x1,y2,x2,1); nodes[m++]=Node(x1,y1,x2,y2,1); nodes2[m]=Node(y2,x1,y1,x2,-1); nodes[m++]=Node(x2,y1,x1,y2,-1); } int ans=0; sort(nodes,nodes+m); sort(y,y+m); UP(i,0,m) { int temp=num[1]; lt=lower_bound(y,y+m,nodes[i].y1)-y+1; rt=lower_bound(y,y+m,nodes[i].y2)-y; v=nodes[i].low; update(1,1,m); ans+=abs(num[1]-temp); } MEM(num,0); MEM(add,0); sort(nodes2,nodes2+m); sort(x,x+m); UP(i,0,m){ y[i]=x[i]; } UP(i,0,m) { int temp=num[1]; lt=lower_bound(x,x+m,nodes2[i].y1)-x+1; rt=lower_bound(x,x+m,nodes2[i].y2)-x; v=nodes2[i].low; update(1,1,m); ans+=abs(num[1]-temp); } printf("%d\n",ans); }}/*20 0 1 10 0 -1 -1*/
阅读全文
0 0
- POJ 1177 Picture (线段树扫描线)
- poj 1177(线段树扫描线)
- POJ 1177 线段树+扫描线
- POJ 1177 线段树+扫描线
- poj 1177 Picture 线段树+离散化+线扫描
- poj 1177 经典线段树+扫描线就周长并
- POJ 1177 Picture (线段树+离散化+扫描线) 详解
- picture 1177 poj 线段树+扫描线+离散化
- poj 1177 / hdu 1828 线段树 离散化 扫描线
- POJ 1177 线段树 扫描线 模板题
- poj - 1177 - Picture(离线化+扫描线+线段树)
- 【线段树+扫描线】 HDOJ 1828 && POJ 1177 Picture
- POJ训练计划1177_Picture(扫描线/线段树+离散)
- 【线段树 + 扫描线】poj 1177 pictures 矩形周长并
- POJ 1177 Picture [离散化+扫描线+线段树]
- POJ - 1177 Picture(线段树 扫描线 区间合并)
- POJ 1177 Picture(线段树+扫描线)
- poj 1177 Picture 【线段树 扫描线 求轮廓周长】
- springcloud(二):注册中心Eureka
- 用filter过滤器实现login入口
- Android平台使用openGL ES 2.0实现预览摄像头数据功能
- 推荐!国外程序员整理的机器学习资源大全
- The folder is already a source folder
- POJ 1177 线段树+扫描线
- leetcode--Sort Colors
- FreeCodeCamp高级算法Advance Algorithm Scripting
- RxJava线程切换流程分析_observeOn
- vscode 集成 git bash.exe
- 写一个函数可以判断一个年份是不是闰年。
- 推荐一款好用的下拉框软件 绿色中文版
- MTK Android Driver :battery
- PHP 分支语句