题意:
      给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次。
思路:
      自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方法,我是离散化横坐标,然后去扫描纵坐标(反过来也行),把每一个长方形的两个宽边拿出来,按照高度排序,然后开始扫描,对于么一个区间的更新,我用的是暴力点更新,因为如果写段更新的话第二个权值没有想到什么好的一起更新的方法。

然后在做另一道题目的时候发现这个方法超时了,没办法又去硬着头皮学了段更新的,段更新的扫描线应该大体有两种,我学了其中一个,然后又用段更新的做了下这个题目。


一开始的暴力区间扫描


#include<stdio.h>
#include<string.h>
#include<algorithm>#define lson l ,mid ,t << 1
#define rson mid + 1 ,r ,t <<1 | 1

using namespace std;typedef struct
{double l ,r ,h;int mk;
}EDGE;EDGE edge[100*2+10];
double sum[100*2*4+10];
double tmp[100*2+10];
double num[100*2+10];
int now[100*2+10];bool camp(EDGE a ,EDGE b)
{return a.h < b.h;
}void Pushup(int t)
{sum[t] = sum[t<<1] + sum[t<<1|1];
}void Update(int l ,int r ,int t ,int a ,int b)
{if(l == r){now[a] += b;if(now[a]) sum[t] = num[a+1] - num[a];else sum[t] = 0;return;}int mid = (l + r) >> 1;if(a <= mid) Update(lson ,a ,b);else Update(rson ,a ,b);Pushup(t);
}int search_2(int n ,double now)
{int low ,up ,mid ,ans;low = 0 ,up = n;while(low <= up){mid = (low + up) >> 1;if(now <= num[mid]){ans = mid;up = mid -  1;}else low = mid + 1;}return ans;
} int main ()
{int n ,i ,j ,cas = 1;double x1 ,x2 ,y1 ,y2;while(~scanf("%d" ,&n) && n){int id = 0;for(i = 1 ;i <= n ;i ++){scanf("%lf %lf %lf %lf" ,&x1 ,&y1 ,&x2 ,&y2);edge[++id].l = x1;edge[id].r = x2 ,edge[id].h = y1 ,edge[id].mk = 1;tmp[id] = x1;edge[++id].l = x1;edge[id].r = x2 ,edge[id].h = y2 ,edge[id].mk = -1;tmp[id] = x2;}sort(tmp + 1 ,tmp + id + 1);sort(edge + 1 ,edge + id + 1 ,camp);tmp[0] = -1;for(id = 0 ,i = 1 ;i <= n * 2 ;i ++)if(tmp[i] != tmp[i-1]) num[++id] = tmp[i];memset(now ,0 ,sizeof(now));memset(sum ,0 ,sizeof(sum));double ans = 0;edge[0].h = edge[1].h;for(i = 1 ;i <= n * 2 ;i ++){ans += sum[1] * (edge[i].h - edge[i-1].h);int l = search_2(id ,edge[i].l);int r = search_2(id ,edge[i].r) - 1;for(j = l ;j <= r ;j ++)Update(1 ,id - 1 ,1 ,j ,edge[i].mk);}printf("Test case #%d\n" ,cas ++);printf("Total explored area: %.2lf\n\n" ,ans);}return 0;
}

后来的段更新扫描

#include<stdio.h>
#include<string.h>
#include<algorithm>#define lson l ,mid ,t << 1
#define rson mid , r ,t << 1 | 1

using namespace std;typedef struct
{double l ,r ,h;int mk;
}EDGE;EDGE edge[1000];double len[1000];
double tmp[1000] ,num[1000];
int cnt[1000];bool camp(EDGE a ,EDGE b)
{return a.h < b.h;
}void Pushup(int l ,int r ,int t)
{if(cnt[t]) len[t] = num[r] - num[l];else if(l + 1 == r) len[t] = 0;else len[t] = len[t<<1] + len[t<<1|1];
}
void Update(int l ,int r ,int t ,int a ,int b ,int c)
{if(l == a && r == b){cnt[t] += c;Pushup(l ,r ,t);return;}int mid = (l + r) >> 1;if(b <= mid) Update(lson ,a ,b ,c);else if(a >= mid) Update(rson ,a ,b ,c);else {Update(lson ,a ,mid ,c);Update(rson ,mid,b ,c);}Pushup(l ,r ,t);
}int search_2(int id ,double now)
{int low ,up ,mid ,ans;low = 1 ,up = id;while(low <= up){mid = (low + up) >> 1;if(now <= num[mid]){ans = mid;up = mid - 1;}else low = mid + 1;}return ans;
}int main ()
{int id ,n ,i ,cas = 1;double x1 ,x2 ,y1 ,y2;while(~scanf("%d" ,&n) && n){for(id = 0 ,i = 1 ;i <= n ;i ++){scanf("%lf %lf %lf %lf" ,&x1 ,&y1 ,&x2 ,&y2);edge[++id].l = x1;edge[id].r = x2 ,edge[id].h = y1 ,edge[id].mk = 1;tmp[id] = x1;edge[++id].l = x1;edge[id].r = x2 ,edge[id].h = y2 ,edge[id].mk = -1;tmp[id] = x2;}sort(tmp + 1 ,tmp + id + 1);sort(edge + 1 ,edge + id + 1 ,camp);memset(len ,0 ,sizeof(len));memset(cnt ,0 ,sizeof(cnt));tmp[0] = -1;for(id = 0 ,i = 1 ;i <= n * 2 ;i ++)if(tmp[i] != tmp[i-1]) num[++id] = tmp[i];double ans = 0;edge[0].h = edge[1].h;for(i = 1 ;i <= n * 2 ;i ++){ans += len[1] * (edge[i].h - edge[i-1].h);int l = search_2(id ,edge[i].l);int r = search_2(id ,edge[i].r);Update(1 ,id ,1 ,l ,r ,edge[i].mk);}printf("Test case #%d\n" ,cas ++);printf("Total explored area: %.2lf\n\n" ,ans);}return 0;
}



hdu1542 线段树扫描线求矩形面积的并相关推荐

  1. hdu1828 线段树扫描线求矩形面积的周长

    题意:       给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路:       线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...

  2. POJ1151(线段树+扫描线求矩形面积并)

    题目:http://poj.org/problem?id=1151 #include <iostream> #include <string.h> #include <a ...

  3. 线段树扫描线求矩形周长详解

    线段树扫描线求矩形周长详解 原创 wucstdio 最后发布于2018-04-24 16:12:09 阅读数 841 收藏 发布于2018-04-24 16:12:09 版权声明:本文为博主原创文章, ...

  4. Picture 线段树扫描线求轮廓线

    http://acm.hdu.edu.cn/showproblem.php?pid=1828 思路来自http://www.cnblogs.com/ka200812/archive/2011/11/1 ...

  5. hdu3255 线段树扫描线求体积

    题意:       给你n个矩形,每个矩形上都有一个权值(该矩形单位面积的价值),矩形之间可能重叠,重叠部分的权值按照最大的算,最后问这n个矩形组成的图形的最大价值. 思路:       线段树扫描线 ...

  6. hdu 1542 Atlantis (线段树+扫描线)

    http://acm.hdu.edu.cn/showproblem.php?pid=1542 单纯的线段树+扫描线求面积并,需要离散化. code: #include <cstdlib> ...

  7. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  8. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

  9. poj 1177 线段树+离散化+扫描线 求矩形并的轮廓长

    Picture 题意:求矩形面积并额轮廓长 解法:扫描线+离散化+线段树 做法:等于更新操作前后的tree[1].len差,做法这么巧妙实际我也不知道为什么.差不多的意思就是更新操作的cover变化长 ...

最新文章

  1. 基于OpenCV的图像梯度与边缘检测!
  2. 科技贡献新力量:无人驾驶清扫车上路
  3. python编程 语言-python编程语言有什么用途
  4. 专属个人的聊天机器人的实现——图灵机器人
  5. http如何像tcp一样实时的收消息?
  6. python下载大文件
  7. css垂直居中那点事
  8. 转载给ffmpeg入门级:我的第一个调用FFmpeg库的程序出炉
  9. 游戏大魔王少不了王者荣耀壁纸图片
  10. 云服务器常用端口及其含义
  11. stm32中断优先级_STM的中断系统
  12. co作为前缀的意思_智课雅思词汇---十五、前缀co-com-con-col-cor-是什么意思
  13. gulp-sass 使用报错Error:gulp-sass no longer has a default Sass compiler; please set one yourself
  14. 华光职业学院计算机专业,关于给予张庆俊等同学省高校计算机一级 考试成绩优秀奖励的通知...
  15. Envoy 架构、术语与基本配置解析
  16. python用pandas读取excel_Python 中利用Pandas处理复杂的Excel数据
  17. [转]不管你学的是什么专业,你都应该多少懂些管理学的东西
  18. 数据库子查询 含义-分类-语句
  19. 【STM32 HAL】用旋钮电位器进行PID调参
  20. Autoware.Auto

热门文章

  1. 解决SecureCRT连接GNS3时SecureCRT标签窗口同名的问题
  2. 无法嵌入互操作类型 请改用适用的接口。
  3. oracle启动服务和监听命令
  4. C#如何制作水晶报表简单易懂示例 转
  5. win10 + GTX1080配置TensorFlow GPU开发环境
  6. PHP对redis操作详解
  7. 在最长的距离二叉树结点
  8. 如何判断应用已经安装,如何判断Service,BroastCastReceiver,ContentProvider是否存在...
  9. HDOJ2019 ( 数列有序! ) 【水题】
  10. sql server 2008 64位连接sql 2000服务器出错解决办法