poj 1151 Atlantis(线段树+离散化+扫描线)
来源:互联网 发布:蜗牛辅助工具淘宝v1.8 编辑:程序博客网 时间:2024/05/18 11:47
题目大意:
在一个平面上有n个矩形,他们可能有部分或全部相互重叠,问矩形的总覆盖面积是多少。
解题思路:
①用一条直线从左向右扫描,每碰到一条矩形的边,就计算当前直线上被矩形覆盖的长度,同时总覆盖面积 += 当前覆盖长度*当前直线到下一条边的距离。碰到矩形左边时,可能使被覆盖长度增加,碰到右边时,可能使长度减少。
②因为一条直线上的一段线段可能被多个矩形同时覆盖,为增加或减少长度是增加困难,所以在扫描时还要记录当前线段被覆盖了几层。
③因为数据是浮点数,所以需要进行离散化。
注意点:
在输出时不知道为什么%.2lf不能过,使用%.2f就可以。
代码:
#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;struct node{ int l,r; double length;//当前线段的被覆盖的长度 int coverd;//当前线段被覆盖了几层};struct segment{ double x,y1,y2; int isLeft;};bool operator < (segment a,segment b){ return a.x < b.x;}int n;node tree[805];double line[205];segment row[205];int lineNum,rowNum;void buildTree(int root,int l,int r){//建树 tree[root].l = l; tree[root].r = r; tree[root].length = 0; tree[root].coverd = 0; if(l != r){ int mid = (l+r)/2; buildTree(2*root,l,mid); buildTree(2*root+1,mid+1,r); }}int findPos(int l,int r,double x){//查询对应竖线的下标 if(l > r) return -1; int mid = (l + r)/2; if(line[mid] == x){ return mid; } else if(line[mid] < x){ findPos(mid+1,r,x); } else{ findPos(l,mid-1,x); }}void updata(int root,int l,int r,int v){//更新线段树 if(tree[root].l == l && tree[root].r == r){ tree[root].coverd += v; if(tree[root].coverd > 0){ tree[root].length = line[r] - line[l-1]; } else{//当此段未被完全覆盖 if(l == r){//如果是叶节点,则覆盖长度为0 tree[root].length = 0; } else{//不是叶节点时,覆盖长度为两个子节点长度的和 tree[root].length = tree[2*root].length + tree[2*root+1].length; } } return; } int mid = (tree[root].l + tree[root].r)/2; if(r <= mid){ updata(2*root,l,r,v); } else if(l > mid){ updata(2*root+1,l,r,v); } else{ updata(2*root,l,mid,v); updata(2*root+1,mid+1,r,v); } if(tree[root].coverd == 0){//若未被完全覆盖,则覆盖长度为两个子节点的和 tree[root].length = tree[2*root].length + tree[2*root+1].length; }}int main(){ int t = 0; double x1,y1,x2,y2; while(cin >> n){ if(n == 0) break; t ++; lineNum = 0; rowNum = 0; for(int i = 0; i < n; i ++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[lineNum++] = y1; line[lineNum++] = y2; row[rowNum].x = x1; row[rowNum].y1 = y1; row[rowNum].y2 = y2; row[rowNum++].isLeft = 1; row[rowNum].x = x2; row[rowNum].y1 = y1; row[rowNum].y2 = y2; row[rowNum++].isLeft = -1; } sort(line,line+lineNum); sort(row,row+rowNum); lineNum = unique(line,line+lineNum) - line; buildTree(1,1,lineNum-1); double pos = 0,ans = 0; for(int i = 0; i < rowNum; i ++){ ans += (row[i].x - pos) * tree[1].length; int up,down; up = findPos(0,lineNum-1,row[i].y1); down = findPos(0,lineNum-1,row[i].y2); updata(1,up+1,down,row[i].isLeft); pos = row[i].x; } printf("Test case #%d\n",t); printf("Total explored area: %.2f\n\n",ans); } return 0;}
0 0
- POJ 1151 Atlantis 离散化 + 扫描线 + 线段树
- POJ 1151 Atlantis 扫描线+离散化+线段树
- POJ 1151 Atlantis(线段树+离散化+扫描线)
- poj-1151 Atlantis(线段树+离散化+扫描线)
- poj 1151 Atlantis (线段树+扫描线+离散化)
- 【POJ】1151 Atlantis(线段树+扫描线+离散化)
- poj 1151 Atlantis 线段树+离散化+扫描线
- poj 1151 Atlantis(线段树+离散化+扫描线)
- poj 1151 Atlantis(线段树+离散化+扫描线)
- POJ 1151 Atlantis 线段树+离散化+扫描线
- poj 1151 Atlantis 线段树扫描线+离散化
- POJ 1542 Atlantis (线段树+扫描线+离散化)
- Atlantis(扫描线+线段树+离散化)
- pku 1151 Atlantis(线段树+离散化+扫描线)
- poj 1151 Atlantis “线段树维护关键值”+“离散化”+“扫描线法”
- 【线段树 + 离散化 + 扫描线】poj 1151 Atlantis 矩形面积并
- POJ题目 1151|| HDOJ 题目1542Atlantis(线段树+离散化+扫描线)
- POJ 1151 & HDU 1542 Atlantis(扫描线模板 线段树 离散化)
- poj1062 昂贵的聘礼 (DFS)
- 一个让我很无语的bug
- git以及github冲突相关的问题
- RSA的简单模拟实现
- 关于Android事件派发流程的理解
- poj 1151 Atlantis(线段树+离散化+扫描线)
- 显示gcc内置宏
- Opencv之Mat类
- Adnroid5.1 最近应用分析(systemui-recents)
- 内存字符串匹配函数
- LintCode:重哈希
- I00012 打印三位数的水仙花数及其个数
- docker1.10.3-jetty8-jersey1.x 构建微服务
- 写PPT装逼的几个工具