HDU-1255 覆盖的面积 矩形面积交
2012-02-24 21:33
295 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1255
题义为给定N个矩形,求其重叠的图形面积,该题采用线段树离散化y轴坐标,并且采用分割思想,只依据x坐标来进行分割。
我们将N个矩形化为N*2条线段来处理,该结构体中的成员变量为 x, yl, yh, 分别是x轴坐标,相对高低的y轴坐标,即线段的两个端点值。
1.将所有的线段排一次序,并将y轴所有坐标轴点排序并进行离散化;
2.在从左往右扫描每一条线段时,我们应该理解为此时我们将把该线段的右边区域认定为全部被覆盖;
3.查找该x轴坐标下被覆盖的y轴坐标的次数,因为一旦y轴被覆盖,则说明其右边无限长的区域被覆盖,如果得到 [y1,y2] 这段区间被覆盖了,那么该点到下一个相邻的x轴的坐标之间
的区域一定是被覆盖的,那么只要这段区间被覆盖2次或以上,这部分的面积就能够求出来了。
代码如下:
题义为给定N个矩形,求其重叠的图形面积,该题采用线段树离散化y轴坐标,并且采用分割思想,只依据x坐标来进行分割。
我们将N个矩形化为N*2条线段来处理,该结构体中的成员变量为 x, yl, yh, 分别是x轴坐标,相对高低的y轴坐标,即线段的两个端点值。
1.将所有的线段排一次序,并将y轴所有坐标轴点排序并进行离散化;
2.在从左往右扫描每一条线段时,我们应该理解为此时我们将把该线段的右边区域认定为全部被覆盖;
3.查找该x轴坐标下被覆盖的y轴坐标的次数,因为一旦y轴被覆盖,则说明其右边无限长的区域被覆盖,如果得到 [y1,y2] 这段区间被覆盖了,那么该点到下一个相邻的x轴的坐标之间
的区域一定是被覆盖的,那么只要这段区间被覆盖2次或以上,这部分的面积就能够求出来了。
代码如下:
#include <cstdlib> #include <cstdlib> #include <cstdio> #include <map> #include <algorithm> #define MAXN 2005 using namespace std; struct Node { double x, yl, yh; int lr; bool operator < (Node t) const { return x < t.x; } }e[MAXN]; struct { int l, r, cover; }seg[3*MAXN]; double yy[MAXN]; void creat(int f, int l, int r) { int mid = (l+r)>>1; seg[f].l = l, seg[f].r = r; seg[f].cover = 0; if (r - l > 1) { creat(f<<1, l, mid); creat(f<<1|1, mid, r); } } void modify(int f, int l, int r, int val) { int mid = (seg[f].l + seg[f].r)>>1; if (seg[f].l == l && seg[f].r == r) { seg[f].cover += val; } else if (seg[f].r - seg[f].l > 1) { if (l >= mid) modify(f<<1|1, l, r, val); else if (r <= mid) modify(f<<1, l, r, val); else { modify(f<<1, l, mid, val); modify(f<<1|1, mid, r, val); } } } void query(int f, double &ans) { if (seg[f].cover > 1) { ans += yy[seg[f].r]-yy[seg[f].l]; // printf("ans = %lf\n", ans); } else if (seg[f].r - seg[f].l > 1) { // if (seg[f].cover != 0) // { seg[f<<1].cover += seg[f].cover; seg[f<<1|1].cover += seg[f].cover; // seg[f].cover = 0; // } // lazy思想处理的话,该题时间上开销要大很多(往下传递过多),所以采用回溯相对较好 query(f<<1, ans); query(f<<1|1, ans); seg[f<<1].cover -= seg[f].cover; seg[f<<1|1].cover -= seg[f].cover; } } int main() { int T, N; double x1, x2, y1, y2, ans, res; scanf("%d", &T); while (T--) { res = 0; map<double,int>mp; scanf("%d", &N); for (int i = 1, j = 1; i <= N; ++i, j+=2) { scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2); e[j].x = x1, e[j].yl = y1, e[j].yh = y2; e[j].lr = 1; e[j+1].x = x2, e[j+1].yl = y1, e[j+1].yh = y2; e[j+1].lr = -1; yy[j] = y1, yy[j+1] = y2; } sort(e+1, e+1+2*N); sort(yy+1, yy+1+2*N); int cnt = unique(yy+1, yy+1+2*N) - (yy+1); creat(1, 1, cnt); for (int i = 1; i <= cnt; ++i) mp[yy[i]] = i; for (int i = 1; i < 2*N; ++i) { ans = 0; modify(1, mp[e[i].yl], mp[e[i].yh], e[i].lr); query(1, ans); res += ans * (e[i+1].x - e[i].x); } printf("%.2lf\n", res); } return 0; }
相关文章推荐
- hdu 1255 覆盖的面积(矩形面积并,多次覆盖)
- hdu 1255 矩形覆盖面积(面积交)
- hdu 1255 覆盖的面积(矩形面积二次交)
- HDU 1255 覆盖的面积 (矩形面积交)
- HDU - 1255 覆盖的面积(线段树-矩形交面积)
- hdu 1255 矩形面积覆盖次数
- hdu 1255 覆盖的面积 矩形D层以上重叠面积
- HDU 1255 覆盖的面积(矩形面积交)
- Hdu 1255 覆盖的面积 线段树+矩形面积并
- HDU-1255 覆盖的面积 (线段树 求矩形覆盖面积)
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
- HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
- HDU 1255 覆盖的面积,矩形面积交
- Hdu 1542 Atlantis + Hdu 1255 覆盖的面积 (线段树矩形面积并)
- hdu 1255 覆盖的面积 求矩形面积交
- HDU 1255 覆盖的面积 (求矩形面积的交)
- HDU 1255 覆盖的面积(线段树求矩形面积交)
- hdu1255 覆盖的面积 线段树+里离散化求矩形面积的交
- HDU 1255 覆盖的面积(矩形交的面积)
- HDU 1255 矩形覆盖面积(线段树)