hdu1542 Atlantis
来源:互联网 发布:无法连接到emule网络 编辑:程序博客网 时间:2024/05/22 03:52
求矩形面积的并,这个题应该是线段树刚刚出现在竞赛时要做的题。
这个题的主要思想就是扫描,我们将所有矩形竖直方向的两条线段,都拿出来排序,然后扫描用线段树维护覆盖的线段长度即可。
对于如上的矩形给所有竖直线段排序后就可以得到下面的图
我们可以观察到从一条线段到下一条线段之前竖直方向的覆盖长度a都不变,而这两条线段之间的距离为b,那么这两条线段之间的面积表示为a * b。
邻近的两条竖直的线段将整个图形分解成若干个部分,我们按上面的方法计算的面积的和就是面积的并了。
为了快速得到竖直方向的覆盖情况,我们用线段树来维护。
比如上图,第一条线段覆盖了a1,到下一条线段的距离为b1,计算面积;第二条与第一条线段共同覆盖了a2,到下一条线段的距离为b2;第三条线段退出覆盖,覆盖的长度为a3(a3==a1),到下一线段的距离为b3....
那么总面积为a1 * b1 + a2 * b2 + a3 * b3 ...
就可以输出答案了。
代码很丑,慢慢看。
#include<cstdio>#include<algorithm>using namespace std;struct node { double x, y;};struct edge { double x; int st, ed; int wt; bool operator < (const edge &rhs) const { return x < rhs.x; }};const int MAXN = 500;int n;node A[MAXN + 10], B[MAXN + 10];int nn;edge Edge[MAXN + 10];int mx;double val[MAXN + 10];struct seg { int l, r; int sig; double cnt; inline double length() { return val[r] - val[l]; } void update(seg &lch, seg &rch) { if(sig) cnt = length(); else { if(l + 1 >= r) cnt = 0; else cnt = lch.cnt + rch.cnt; } }} Tree[MAXN * 4 + 10];void Build(int u, int l, int r) { seg &cur = Tree[u]; cur.l = l, cur.r = r; cur.cnt = cur.sig = 0; if(l + 1 >= r) return ; int mid = (l + r) / 2; Build(u * 2, l, mid); Build(u * 2 + 1, mid, r);}void Ins(int u, int l, int r, int x) { seg &cur = Tree[u], &lch = Tree[u * 2], &rch = Tree[u * 2 + 1]; if(cur.l >= r || cur.r <= l) return ; else if(l <= cur.l && cur.r <= r) cur.sig += x; else { Ins(u * 2, l, r, x); Ins(u * 2 + 1, l, r, x); } cur.update(lch, rch);}double work() { mx = nn = 0; for(int i = 1; i <= n; i++) val[++mx] = A[i].y, val[++mx] = B[i].y; sort(val + 1, val + 1 + mx); mx = unique(val + 1, val + 1 + mx) - val - 1; for(int i = 1; i <= n; i++) { int y1 = lower_bound(val + 1, val + 1 + mx, A[i].y) - val, y2 = lower_bound(val + 1, val + 1 + mx, B[i].y) - val; Edge[++nn] = (edge){A[i].x, y1, y2, 1}; Edge[++nn] = (edge){B[i].x, y1, y2, -1}; } sort(Edge + 1, Edge + 1 + nn); double ans = 0; double Last = 0; Build(1, 1, mx); for(int i = 1; i <= nn; i++) { if(i != 1) ans += Tree[1].cnt * (Edge[i].x - Last); Last = Edge[i].x; Ins(1, Edge[i].st, Edge[i].ed, Edge[i].wt); } return ans;}int main() { int kase = 0; while(scanf("%d", &n) == 1 && n) { for(int i = 1; i <= n; i++) { scanf("%lf%lf", &A[i].x, &A[i].y); scanf("%lf%lf", &B[i].x, &B[i].y); } printf("Test case #%d\nTotal explored area: %.2f\n\n", ++kase, work()); } return 0;}
相应的我们也会求矩形面积的交、并、以及周长了。
poj1177 求轮廓周长
hdu1255 求面积的交
hdu4419 也可以算求矩形面积的交吧
hdu4052 可以转化模型为求矩形面积的并
0 0
- hdu1542 Atlantis
- HDU1542--Atlantis
- [HDU1542]Atlantis
- hdu1542----Atlantis
- hdu1542 Atlantis
- hdu1542 Atlantis
- hdu1542 Atlantis 面积交
- HDU1542 Atlantis(面积并)
- 线段树 hdu1542 Atlantis
- HDU1542 Atlantis (扫描线)
- hdu1542 Atlantis--扫描线
- HDU1542&&POJ1151-Atlantis
- [题解]hdu1542 Atlantis
- hdu1542 Atlantis (线段树+扫描线)
- hdu1542 Atlantis(矩形面积并)
- HOJ1119/HDU1542 Atlantis HOJ1909/POJ1177 Picture
- 面积并---扫描线 hdu1542 Atlantis
- POJ1151 HDU1542 CODEVS3044 Atlantis 题解&代码
- Ubuntu 12.04 ros install and uninstall
- HTML5学习笔记
- vim常用命令
- Android文字描边
- 分支-01. 超速判断
- hdu1542 Atlantis
- HDU1000
- 职场经典定律 http://my.weibo.com/u
- Markdown语法学习
- 【字符串拷贝函数】memcpy strcpy strncpy lstrcpy lstrncpy wstrcpy的区别
- 试卷导出,poi操作
- CSerial串口类
- Java7
- Struts的取值与标签