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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

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

發(fā)布時間:2025/4/9 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

鏈接:線段樹求矩形面積并 掃描線+離散化

1、給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區(qū)域的面積.

2、看完線段樹求矩形面積并 的方法后,再看這題,求的是矩形面積交,類同。

求面積時,用被覆蓋2次以上的那一段乘以掃描線的距離即可,具體實(shí)現(xiàn)見代碼。

3、

/* HDU 1255 覆蓋的面積 求矩形面積交(離散化+線段樹) 給定一些矩形 求被這些矩形覆蓋過至少兩次的區(qū)域的面積這里的方法是:線段樹求矩形面積交 掃描線+離散化 左右掃描(x軸掃描),把y軸上的線段離散化 */ #include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> using namespace std;const int MAXN=2005;struct Node {int l,r;//離散化后的y值double lf,rf;//原來的y值,lf代表l原來的y值,rf代表r原來的y值int cnt;//當(dāng)前段被覆蓋過幾次double lenOnce;//當(dāng)前段中覆蓋一次以上的長度double lenTwice;//當(dāng)前段中覆蓋兩次以上的長度 } segTree[MAXN*4]; struct Line {double x;//也就是對應(yīng)的掃描線x坐標(biāo)double y1,y2;//線段的端點(diǎn)坐標(biāo)double f;//1表示一個矩形左邊的邊,-1表示右邊的邊 } line[MAXN];double y[MAXN];bool cmp(Line a,Line b) {return a.x<b.x; }void Build(int i,int l,int r) {segTree[i].l=l;segTree[i].r=r;segTree[i].lenOnce=0;segTree[i].lenTwice=0;segTree[i].lf=y[l];segTree[i].rf=y[r];if(l+1==r)return;int mid=(l+r)>>1;Build(i<<1,l,mid);Build((i<<1)|1,mid,r); } void calen(int i) {if(segTree[i].cnt>=2)//被線段覆蓋次數(shù)>=2 {segTree[i].lenOnce=segTree[i].rf-segTree[i].lf;segTree[i].lenTwice=segTree[i].rf-segTree[i].lf;return;}else if(segTree[i].cnt==1)//被線段覆蓋次數(shù)==1 {segTree[i].lenOnce=segTree[i].rf-segTree[i].lf;if(segTree[i].l+1==segTree[i].r)segTree[i].lenTwice=0;//當(dāng)是葉子節(jié)點(diǎn)時else segTree[i].lenTwice=segTree[i<<1].lenOnce+segTree[(i<<1)|1].lenOnce;//因?yàn)楫?dāng)前線段被覆蓋過1次,所以覆蓋2次以上的長度是其左右孩子的覆蓋1次以上的長度的和 }else//被線段覆蓋次數(shù)==0 {if(segTree[i].l+1==segTree[i].r)//當(dāng)是葉子節(jié)點(diǎn)時 {segTree[i].lenOnce=segTree[i].lenTwice=0;}else{//因?yàn)楫?dāng)前節(jié)點(diǎn)被覆蓋次數(shù)為0,所以lenOnce和lenTwice的值由左右孩子決定segTree[i].lenOnce=segTree[i<<1].lenOnce+segTree[(i<<1)|1].lenOnce;segTree[i].lenTwice=segTree[i<<1].lenTwice+segTree[(i<<1)|1].lenTwice;}} } void update(int i,Line e) {if(e.y1==segTree[i].lf&&segTree[i].rf==e.y2){segTree[i].cnt+=e.f;calen(i);//更新當(dāng)前節(jié)點(diǎn)信息return;}if(e.y2<=segTree[i<<1].rf) update(i<<1,e);else if(e.y1>=segTree[(i<<1)|1].lf) update((i<<1)|1,e);else{Line temp=e;temp.y2=segTree[i<<1].rf;update(i<<1,temp);temp=e;temp.y1=segTree[(i<<1)|1].lf;update((i<<1)|1,temp);}calen(i);//更新當(dāng)前節(jié)點(diǎn)信息 } int main() {//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int T;int n;double x1,y1,x2,y2;scanf("%d",&T);while(T--){scanf("%d",&n);int t=1;for(int i=1; i<=n; i++){scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);//這里題目描述有問題?左下角和右上角line[t].y1=y1;line[t].y2=y2;line[t].x=x1;line[t].f=1;//左邊的邊y[t]=y1;//y坐標(biāo)離散化(下端點(diǎn))t++;line[t].y1=y1;line[t].y2=y2;line[t].x=x2;line[t].f=-1;//右邊的邊y[t]=y2;//y坐標(biāo)離散化(上端點(diǎn))t++;}sort(line+1,line+t,cmp);//線段按x的值升序排序sort(y+1,y+t);//y坐標(biāo)從小下到大排序Build(1,1,t-1);//用離散化后的y值(也就是t)建立線段樹 update(1,line[1]);//從第一條掃描線向右掃描double ans=0;for(int i=2; i<t; i++){ans+=segTree[1].lenTwice*(line[i].x-line[i-1].x);update(1,line[i]);}printf("%.2lf\n",ans);}return 0; } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/bofengyu/p/4964641.html

總結(jié)

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

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