HDU 1828 / POJ 1177 Picture 初涉扫描线
来源:互联网 发布:python 递归深度 编辑:程序博客网 时间:2024/05/16 04:58
先贴个代码,题解明天补上,先去补读书笔记。。。
熬夜通宵补完了坑爹的读书笔记和社会实践报告,七千字额,呕心沥血的大作
题意:一个二维的平面内许多边平行于坐标轴的矩形相交,组成了比较复杂的多边行,求多边形的周长。
思路:一开始感觉数据范围这么大,肯定要用线段树优化的,结果作了半天的线段书,也没想出该怎么维护。。。。。。感觉弱爆了。。。。。。然后试了试不用线段树,结果31MS水过了。。
下面说一下自己对扫描线的理解:
扫描线给人的感觉就是在目标区域内有一条线按照一定的要求从一端扫到另一端,在扫描的过程内会碰到事先标记好的事件点,从而计算目标值。
对于这道题来说,目标值就是多边形的周长,事件点即为矩形的边。
以与Y轴平行的边为例。
扫描线的每条线段初始值为零,每次碰到左边则加一,碰到右边则减一,当标记从0变为1或从1变为0时,加上这一小段的值,当然还要注意去重边,如下面这组数据。
2
0 0 2 2
2 1 3 3
显然与X轴平行的边也一样计算。
#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <cmath>#include <algorithm>#define LL long long#define Max(a,b) (a) > (b) ? (a) : (b)#define Min(a,b) (a) < (b) ? (a) : (b)#define EPS (1e-8)#define Left (1)#define Right (-1)using namespace std;struct P{ int x,y;};struct L{ P p1,p2; int mark;}lx[10100],ly[10100];struct S{ int cover,site;}seg[10100];int px[10010],py[10010];int delsame(int *p,int n){ if(n == 0) return 0; int top,i; for(i = 1,top = 1;i < n; ++i) { if(p[i] != p[i-1]) p[top++] = p[i]; } return top;}bool cmp(int a,int b){ return a < b;}bool cmp_x(L l1,L l2){ return l1.p1.x < l2.p1.x;}bool cmp_y(L l1,L l2){ return l1.p1.y < l2.p1.y;}int BS(int *p,int m,int n){ int s = 0,e = n - 1,mid; while(s < e) { mid = (s+e)>>1; if(p[mid] == m) return mid; if(p[mid] < m) { s = mid+1; } else { e = mid-1; } } mid = (s+e)>>1; if(p[mid] == m) return mid; return -1;}int main(){ int n; int t1,t2,ty,tx; P p1,p2; int i,j,s1,s2; int Perimeter; while(scanf("%d",&n) != EOF) { Perimeter = 0; t1 = t2 = tx = ty = 0 ; for(i = 0;i < n; ++i) { scanf("%d %d %d %d",&p1.x,&p1.y,&p2.x,&p2.y); lx[t1].p1 = p1; lx[t1].p2.x = p2.x; lx[t1].p2.y = p1.y; lx[t1].mark = Left; ++t1; lx[t1].p2 = p2; lx[t1].p1.x = p1.x; lx[t1].p1.y = p2.y; lx[t1].mark = Right; ++t1; ly[t2].p1 = p1; ly[t2].p2.x = p1.x; ly[t2].p2.y = p2.y; ly[t2].mark = Left; ++t2; ly[t2].p2 = p2; ly[t2].p1.x = p2.x; ly[t2].p1.y = p1.y; ly[t2].mark = Right; ++t2; px[tx++] = p1.x; px[tx++] = p2.x; py[ty++] = p1.y; py[ty++] = p2.y; } sort(px,px+ty,cmp); sort(py,py+ty,cmp); sort(lx,lx+t1,cmp_y); sort(ly,ly+t2,cmp_x); tx = delsame(px,tx); ty = delsame(py,ty); for(i = 0;i <= tx; ++i) { seg[i].cover = 0; seg[i].site = -10010; } for(i = 0;i < t1; ++i) { s1 = BS(px,lx[i].p1.x,tx); s2 = BS(px,lx[i].p2.x,tx); for(j = s1;j < s2; ++j) { if(seg[j].cover == 0) { if(seg[j].site != lx[i].p1.y) { Perimeter += (px[j+1]-px[j]); } else { Perimeter -= (px[j+1]-px[j]); } seg[j].site = lx[i].p1.y; seg[j].cover += lx[i].mark; } else { seg[j].cover += lx[i].mark; if(seg[j].cover == 0) { Perimeter += (px[j+1]-px[j]); seg[j].site = lx[i].p1.y; } } } } for(i = 0;i <= ty; ++i) { seg[i].cover = 0; seg[i].site = -10010; } for(i = 0;i < t2; ++i) { s1 = BS(py,ly[i].p1.y,ty); s2 = BS(py,ly[i].p2.y,ty); for(j = s1;j < s2; ++j) { if(seg[j].cover == 0) { if(seg[j].site != ly[i].p1.x) { Perimeter += (py[j+1]-py[j]); } else { Perimeter -= (py[j+1]-py[j]); } seg[j].site = ly[i].p1.x; seg[j].cover += ly[i].mark; } else { seg[j].cover += ly[i].mark; if(seg[j].cover == 0) { Perimeter += (py[j+1]-py[j]); seg[j].site = ly[i].p1.x; } } } } cout<<Perimeter<<endl; } return 0;}
- HDU 1828 / POJ 1177 Picture 初涉扫描线
- POJ 1177 Picture & hdu 1828 Picture(扫描线)
- POJ 1177 & HDU 1828 Picture(扫描线 + 求周长)
- hdu 1828 Picture(扫描线)
- Picture hdu 1828 扫描线
- hdu 1828(poj 1177)Picture(线段树+扫描线)(轮廓线)
- HDU 1828 && POJ 1177 Picture(线段树+扫描线+离散化)
- poj 1177 || HDU 1828 Picture (线段树扫描线求 图形并的周长)
- 【线段树+扫描线】 HDOJ 1828 && POJ 1177 Picture
- poj 1177 picture (扫描线)
- POJ 1177 Picture(扫描线求周长)
- POJ 1177 Picture (线段树扫描线)
- HDU 1828 Picture(线段树:扫描线)
- HDU 1828 Picture 扫描线 求周长
- hdu 1828 Picture 线段树+扫描线
- poj 1177 Picture 线段树+离散化+线扫描
- POJ 1177 Picture (线段树+离散化+扫描线) 详解
- picture 1177 poj 线段树+扫描线+离散化
- 详解C#引用类型String
- 九。内核同步问题
- 《REWORK》启示录 音乐应在你的指尖流淌——工具和代码无关
- wifi for win8
- JavaScript中的匿名函数及函数的闭包
- HDU 1828 / POJ 1177 Picture 初涉扫描线
- DuplicateHandle的应用
- ASP遍历Session
- CODE 114: 4Sum
- OCP-1Z0-053-V12.02-577题
- 数据恢复软件设计与实现(五)
- 对PowerPC的学习笔记
- 一个技术男的纠结
- 最小二乘