POJ 1151 Atlantis 線段樹/矩形面積並

來源:互聯網
上載者:User

題意:求矩形的面積並。
題解:

求矩形的並,由於矩形的位置可以多變,因此矩形的面積一下子不好求

這個時候,可以採用“分割”的思想,即把整塊的矩形面積分割成幾個小矩形的面積,然後求和就行了

這裡我們可以這樣做,把每個矩形投影到 y 座標軸上來

然後我們可以枚舉矩形的 x 座標,然後檢測當前相鄰 x 座標上 y 方向的合法長度,兩種相乘就是面積

 

然後關鍵就是如何用線段樹來維護那個 “合法長度”

可以這樣來搞

線段樹的節點這樣定義

struct node { int left,right,cov; double len; }

cov 表示當前節點區間是否被覆蓋,len 是當前區間的合法長度

 

然後我們通過“掃描線”的方法來進行掃描

枚舉 x 的豎邊,矩形的左邊那條豎邊就是入邊,右邊那條就是出邊了

然後把所有這些豎邊按照 x 座標遞增排序,每次進行插入操作

由於座標不一定為整數,因此需要進行離散化處理

每次插入時如果當前區間被完全覆蓋,那麼就要對 cov 域進行更新

入邊 +1 出邊 -1

更新完畢後判斷當前節點的 cov 域是否大於 0

如果大於 0,那麼當前節點的 len 域就是節點所覆蓋的區間

否則

如果是葉子節點,則 len=0

如果內部節點,則 len=左右兒子的 len 之和
以上轉自http://hi.baidu.com/legend_ni/blog/item/106e9f8a34ff9b04b21bba71.html

看的暈暈的,其實只需要自己畫個圖分析分析便可理解。

#include <algorithm>#include <iostream>using namespace std;#define L(x) ( x << 1 )#define R(x) ( x << 1 | 1 )double y[1000]; struct Line{double x, y1, y2;int flag;} line[300];struct Node{int l, r, cover;double lf, rf, len;} node[1000];bool cmp ( Line a, Line b ){return a.x < b.x;}void length ( int u ){if ( node[u].cover > 0 ){node[u].len = node[u].rf - node[u].lf;return;}else if ( node[u].l + 1 == node[u].r )node[u].len = 0; /* 葉子節點,len 為 0 */else    node[u].len = node[L(u)].len + node[R(u)].len;}void build ( int u, int l, int r ){node[u].l = l; node[u].r = r;node[u].lf = y[l]; node[u].rf = y[r];node[u].len = node[u].cover = 0;if ( l + 1 == r ) return;int mid = ( l + r ) / 2;build ( L(u), l, mid );build ( R(u), mid, r );}void update ( int u, Line e ){if ( e.y1 == node[u].lf && e.y2 == node[u].rf ){node[u].cover += e.flag;length ( u );return;}if ( e.y1 >= node[R(u)].lf )update ( R(u), e );else if ( e.y2 <= node[L(u)].rf )update ( L(u), e );else{Line temp = e;temp.y2 = node[L(u)].rf;update ( L(u), temp );temp = e;temp.y1 = node[R(u)].lf;update ( R(u), temp );}length ( u );}int main(){//freopen("a.txt","r",stdin);int n, t, i, Case = 0;double  x1, y1, x2, y2, ans;while ( scanf("%d",&n) && n ){for ( i = t = 1; i <= n; i++, t++ ){scanf("%lf%lf%lf%lf",&x1, &y1, &x2, &y2 );line[t].x = x1;line[t].y1 = y1;line[t].y2 = y2;line[t].flag = 1;y[t] = y1;t++;line[t].x = x2;line[t].y1 = y1;line[t].y2 = y2;line[t].flag = -1;y[t] = y2;}sort ( line + 1, line + t, cmp );sort ( y + 1, y + t );build ( 1, 1, t-1 );        update ( 1, line[1] );ans = 0;for ( i = 2; i < t; i++ ){ans += node[1].len * ( line[i].x - line[i-1].x );update ( 1, line[i] );}printf ( "Test case #%d\n", ++Case );printf ( "Total explored area: %.2lf\n\n", ans );}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.