hdu1542 线段树扫描线求矩形面积的并
来源:互联网 发布:淘宝内存卡骗局大全 编辑:程序博客网 时间:2024/05/21 06:40
题意:
给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次。
思路:
自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方法,我是离散化横坐标,然后去扫描纵坐标(反过来也行),把每一个长方形的两个宽边拿出来,按照高度排序,然后开始扫描,对于么一个区间的更新,我用的是暴力点更新,因为如果写段更新的话第二个权值没有想到什么好的一起更新的方法。
给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次。
思路:
自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方法,我是离散化横坐标,然后去扫描纵坐标(反过来也行),把每一个长方形的两个宽边拿出来,按照高度排序,然后开始扫描,对于么一个区间的更新,我用的是暴力点更新,因为如果写段更新的话第二个权值没有想到什么好的一起更新的方法。
然后在做另一道题目的时候发现这个方法超时了,没办法又去硬着头皮学了段更新的,段更新的扫描线应该大体有两种,我学了其中一个,然后又用段更新的做了下这个题目。
一开始的暴力区间扫描
#include<stdio.h>
#include<string.h>#include<algorithm>#define lson l ,mid ,t << 1#define rson mid + 1 ,r ,t <<1 | 1using 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 | 1using 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;}
0 0
- hdu1542 线段树扫描线求矩形面积的并
- HDU1542 线扫描求矩形面积并
- HDU1542 Atlantis(扫描线+矩形面积并+线段树)
- 线段树扫描线面积并hdu1542
- 扫描线+线段树求矩形面积的并
- HDU1542——Atlantis(扫描线,线段树,矩形面积并,离散化)
- HDU1542 Atlantis 扫描线 矩形面积并
- hdu1542 线段树 矩形面积并
- 【HDU1542】Atlantis【线段树】【矩形面积并】
- hdu1542 Atlantis【矩形面积并+线段树】
- POJ1151(线段树+扫描线求矩形面积并)
- 线段树求矩形面积并 扫描线+离散化
- 线段树求矩形面积并 扫描线+离散化
- hdu1255 覆盖的面积(线段树+扫描线+离散化,求矩形面积并)
- hdu1542-Atlantis 线段树+扫描线+离散化 求面积并
- 线段树、扫描线、离散化求面积并(hdu1542)
- hdu1542(扫描线求面积并)
- HDU1542-Atlantis(线段树+扫描线——面积并)
- 分页
- 【OpenCV】访问Mat中每个像素的值(新)(III)
- HDU 3549 Flow Problem
- Linux开启mysql远程连接的设置步骤
- 按用户名查询
- hdu1542 线段树扫描线求矩形面积的并
- iOS 常用控件的使用方法
- 小记,随时记录开发中的事
- HDU 3572 Task Schedule
- 【从开发者角度看测试】php+mysql+js登录注册系统
- scala学习笔记3(trait)
- 张小龙演讲全文:如何把产品做简单
- POJ--2709:Painter (贪心)
- LeetCode 55 Interleaving String