日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu1542 线段树扫描线求矩形面积的并

發(fā)布時間:2025/6/17 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu1542 线段树扫描线求矩形面积的并 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:
? ? ? 給你n個正方形,求出他們的所占面積有多大,重疊的部分只能算一次。
思路:
? ? ? 自己的第一道線段樹掃描線題目,至于掃描線,最近會寫一個總結(jié),現(xiàn)在就不直接在這里寫了,說下我的方法,我是離散化橫坐標(biāo),然后去掃描縱坐標(biāo)(反過來也行),把每一個長方形的兩個寬邊拿出來,按照高度排序,然后開始掃描,對于么一個區(qū)間的更新,我用的是暴力點更新,因為如果寫段更新的話第二個權(quán)值沒有想到什么好的一起更新的方法。

然后在做另一道題目的時候發(fā)現(xiàn)這個方法超時了,沒辦法又去硬著頭皮學(xué)了段更新的,段更新的掃描線應(yīng)該大體有兩種,我學(xué)了其中一個,然后又用段更新的做了下這個題目。


一開始的暴力區(qū)間掃描

#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; }



《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的hdu1542 线段树扫描线求矩形面积的并的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。