HDU 1542 Atlantis(矩形面积并,线段树+离散化+线扫描)
2017-08-01 17:45
471 查看
题目链接:点击打开链接
题意:矩形面积并
思路:由于数据较大,浮点数先要离散化;然后把矩形分成两类边,上边和下边,相关信息存到结构体中;对离散化后的横轴建线段树,然后对于每条边,自下而上扫描上去,每次扫描到的块为当前边与下一条边之间的块,sum代表区间内被覆盖的线段的长度总和,那么sum[1]就表示当前块 线段(横轴)的总长度,每次处理用sum[1] * 当前块height就是该块面积;这里线段树的一个结点并非是线段的一个端点,而是该端点和下一个端点间的线段,所以题目中r+1,r-1的地方要仔细琢磨。
对于cnt,要考虑仔细,每个区间,cnt均可叠加,表面上cnt表示该区间下边比上边多几个,实际update后,cnt已经表明了整个区间在当前块的线段分布,cnt不为零的区间,均有线段,sum也会不为零,算法正确性一目了然
题意:矩形面积并
思路:由于数据较大,浮点数先要离散化;然后把矩形分成两类边,上边和下边,相关信息存到结构体中;对离散化后的横轴建线段树,然后对于每条边,自下而上扫描上去,每次扫描到的块为当前边与下一条边之间的块,sum代表区间内被覆盖的线段的长度总和,那么sum[1]就表示当前块 线段(横轴)的总长度,每次处理用sum[1] * 当前块height就是该块面积;这里线段树的一个结点并非是线段的一个端点,而是该端点和下一个端点间的线段,所以题目中r+1,r-1的地方要仔细琢磨。
对于cnt,要考虑仔细,每个区间,cnt均可叠加,表面上cnt表示该区间下边比上边多几个,实际update后,cnt已经表明了整个区间在当前块的线段分布,cnt不为零的区间,均有线段,sum也会不为零,算法正确性一目了然
// HDU 1542 Atlantis.cpp 运行/限制:0ms/1000ms #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; #define MAXN 500 #define lson l, m, root << 1 #define rson m + 1, r, root << 1 | 1 struct edge { double lpoint, rpoint, height; int flag; edge(){} edge(double a,double b,double c,int d):lpoint(a),rpoint(b),height(c),flag(d){} bool operator <(const edge& b)const { return this->height < b.height; } }; double point[MAXN]; int cnt[MAXN << 2]; double sum[MAXN << 2]; edge edges[MAXN]; int binarySearch(double num, int l, int r, double a[]) { while (l <= r) { int m = (l + r) >> 1; if (fabs(num - a[m]) <= 1e-6) { return m; } else if (num > a[m]) { l = m + 1; } else { r = m - 1; } } return -1; } void pushUp(int root,int l,int r) { if (cnt[root]) { sum[root] = point[r + 1] - point[l]; } else if (l == r) { sum[root] = 0.0; } else { sum[root] = sum[root << 1] + sum[root << 1 | 1]; } } void update(int le, int rig, int value, int l, int r, int root) { if (le <= l && rig >= r) { cnt[root] += value; pushUp(root,l,r); return; } int m = (l + r) >> 1; if (le <= m) { update(le, rig, value, lson); } if (rig > m) { update(le, rig, value, rson); } pushUp(root,l,r); } int main(){ int n, count = 0; double a, b, c, d; while (scanf("%d", &n) != EOF && n) { int m = 0; for (int i = 0; i < n; i++) { scanf("%lf%lf%lf%lf", &a, &b, &c, &d); point[m] = a; edges[m++] = edge(a, c, b, 1);//下边 point[m] = c; edges[m++] = edge(a, c, d, -1);//上边 } sort(point, point + m); sort(edges, edges + m); int k = 1; for (int i = 1; i < m; i++) { if (point[i] != point[i - 1]) { point[k++] = point[i]; } } memset(cnt, 0, sizeof(cnt)); memset(sum, 0, sizeof(sum)); double re = 0.0; for (int i = 0; i < m - 1; i++) { int l = binarySearch(edges[i].lpoint,0,k - 1,point); int r = binarySearch(edges[i].rpoint,0,k - 1,point) - 1; if (l <= r) { update(l, r, edges[i].flag, 0, k - 1, 1); } re += sum[1] * (edges[i + 1].height - edges[i].height); } printf("Test case #%d\nTotal explored area: %.2f\n\n",++count,re); } return 0; }
相关文章推荐
- POJ1151 (HDU 1542) Atlantis【矩形面积并,线段树+离散化+扫描线模板】
- HDU1542——Atlantis(扫描线,线段树,矩形面积并,离散化)
- HDU-1542/POJ-1151 Atlantis(矩形并面积--线段树+离散化)
- HDU 1542【线段树--矩形面积的并,扫描线+离散化】
- HDU1542 Atlantis(扫描线+矩形面积并+线段树)
- HDU-1542 Atlantis 矩形面积并 扫描线
- hdu 1542 Atlantis 线段树+矩形面积并+离散化点
- HDU 1542 —— Atlantis 【矩形面积并:扫描线】
- hdu 1542 & poj 1151 Atlantis 线段树扫描线求矩形面积并
- http://acm.hdu.edu.cn/showproblem.php?pid=1542 矩形面积的并 线段树 + 扫描线 + 离散化
- HDU 1542 Atlantis(离散化+扫描线(求并面积)+线段树)
- 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)
- poj 1151 Atlantis / hdu 1542 线段树扫描线 矩形面积并
- hdu 1255 线段树+离散化+扫描线 (矩形面积交
- hdu 1542 Atlantis(线段树进阶,扫描线,矩形面积并)
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
- [HDU] 1542 - Atlantis - 矩形并 - 离散化 - 扫描线 - 线段树
- HDU 1542 —— Atlantis 【矩形面积并:扫描线】
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
- POJ1151 Atlantis(线段树,扫描线,离散化,矩形面积并)