poj 1177 / hdu 1828 Picture 矩形周长并
2012-08-11 14:06
357 查看
分x边和y边两次线段树扫描线,寻找cover值0->1的区域,长度*2即可。
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int maxn=20005; const int TT=10000; int n; struct rect{ int x1, y1, x2, y2; }rec[maxn]; struct node{ int lef, rig, mid, cover; }seg[maxn*4]; struct line{ int x1, x2, y, flag; }l[maxn]; void make_tree(int num, int lef, int rig){ seg[num].lef=lef; seg[num].rig=rig; seg[num].mid=(lef+rig)/2; seg[num].cover=0; if(lef+1!=rig){ make_tree(num*2, lef, seg[num].mid); make_tree(num*2+1, seg[num].mid, rig); } } int insert(int num, int lef, int rig, int cover, int f){ if(seg[num].cover!=-1&&seg[num].lef==lef&&seg[num].rig==rig){ if(cover==1&&seg[num].cover==0&&f){ seg[num].cover+=cover; return seg[num].rig-seg[num].lef; } seg[num].cover+=cover; return 0; } if(seg[num].cover>0){ insert(num*2, seg[num].lef, seg[num].mid, seg[num].cover, 0); insert(num*2+1, seg[num].mid, seg[num].rig, seg[num].cover, 0); seg[num].cover=-1; } seg[num].cover=-1; if(rig<=seg[num].mid) return insert(num*2, lef, rig, cover, f); else if(lef>=seg[num].mid) return insert(num*2+1, lef, rig, cover, f); else { return insert(num*2, lef, seg[num].mid, cover, f)+ insert(num*2+1, seg[num].mid, rig, cover, f); } } void init(int t){ for(int i=0; i<n; i++){ if(t==1){ l[i*2].x1=rec[i].x1; l[i*2].y=rec[i].y1; l[i*2+1].x2=rec[i].x2; l[i*2+1].y=rec[i].y2; } else { l[i*2].x1=rec[i].y1; l[i*2].y=rec[i].x1; l[i*2+1].x2=rec[i].y2; l[i*2+1].y=rec[i].x2; } l[i*2].x1+=TT; l[i*2].y+=TT; l[i*2+1].x2+=TT; l[i*2+1].y+=TT; l[i*2].x2=l[i*2+1].x2; l[i*2+1].x1=l[i*2].x1; l[i*2].flag=1; l[i*2+1].flag=-1; } } bool cmpy(line l1, line l2){ return l1.y<l2.y; } int solve(){ int ans=0; make_tree(1, 0, TT*2); sort(l, l+2*n, cmpy); for(int i=0; i<2*n-1; i++){ ans+=2*insert(1, l[i].x1, l[i].x2, l[i].flag, 1); } return ans; } int main(){ //freopen("1.txt", "r", stdin); while(scanf("%d", &n)!=EOF){ for(int i=0; i<n; i++) scanf("%d%d%d%d", &rec[i].x1, &rec[i].y1, &rec[i].x2, &rec[i].y2); init(1); int ans=solve(); init(2); ans+=solve(); printf("%d\n", ans); } return 0; }
相关文章推荐
- hdu 1828 / poj/pku 1177(Picture)(线段树求矩形覆盖面周长)
- poj 1177 & hdu 1828 Picture 线段树 扫描线求矩形周长并
- POJ - 1177/HDU - 1828 Picture(线段树-矩形并周长)
- POJ 1177 Picture(矩形并的周长)
- HDU 1828 / POJ 1177 Picture --线段树求矩形周长并
- poj 1177 Picture(线段树求矩形周长并)
- POJ-1177 Picture 矩形覆盖周长并
- POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算
- hdu 1828、poj1177求矩形周长并 线段树 扫描线
- poj1177 Picture 矩形周长并
- poj 1177 & hdu 1828 矩形周长并
- poj 1177 Picture(扫描线+矩形周长并)
- HDU 1828 / POJ 1177 Picture --线段树求矩形周长并
- POJ-1177 Picture (线段树 求矩形周长)
- poj 1177 || HDU 1828 Picture (线段树扫描线求 图形并的周长)
- POJ 1177 Picture 求多个矩形周长 -
- poj 1177 Picture(线段树+矩形周长并)
- POJ 1177 Picture(扫描线 + 线段树 矩形覆盖区域周长的并)
- POJ 1177 Picture 矩形周长并
- hdoj 1828 (poj 1177) 线段树求矩形并的周长