參考部落格:
方法:把矩形分成橫線和豎線去處理,可知是完全相同的操作,我們來講下怎麼算出橫線部分,豎線部分就是照搬即可。
將橫線儲存在乙個表中,按橫線所處的豎直位置排序(公升序),另外每條橫線帶乙個標記值,原矩形的下線為1,上線為-1(對應過去就是插入線段和刪除線段)
從低到高掃瞄橫線,沒掃到一條橫線就能計算出一部分橫線值。計算方法是算出現在總區間的被覆蓋的長度,然後求出與上一次的總區間的覆蓋長度的差(即相減求絕對值),因為每次新增了一條線段,如果沒有沒有使總區間覆蓋長度發生變化,說明這條線段其實在多邊形的內部,被覆蓋掉了,不能計算,只要能引起總區間長度發生變化的,說明該線段不被覆蓋不被包含,要計算。
而豎線部分的做法是一樣的,把豎線儲存在乙個表中,按水平位置排序(公升序),每條橫線帶乙個標記值,原矩形的左線為1,右線為-1,然後同樣地操作
我用的是第一種方法,思路和上面的部落格一樣,只有乙個地方需要注意。
注意:掃瞄線的排序方法 return a.h==b.h?a.status>b.status:a.h
為什麼這麼排序?樣例 :2 0 0 1 1 0 1 1 2 自己手動模擬一下這組樣例就會明白了
**:
///#include///#include///#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define mt(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double e=2.718281828459;
const int maxn=1e5;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
struct node
pushup(sign,l,r);
}int main()
; line[++sign]=node;
x[sign]=x1;
line[++sign]=node;
x[sign]=x2;
}sort(line+1,line+1+sign);
sort(x+1,x+1+sign);
int d=unique(x+1,x+1+sign)-(x+1);
ll len=abs(line[sign].r-line[sign].l);
ll pre=0;
for(int i=1;imemset(root,0,sizeof(root));
sign=0;
for(int i=1;i<=n;i++)
;x[sign]=y1;
line[++sign]=node;
x[sign]=y2;
}sort(x+1,x+1+sign);
sort(line+1,line+1+sign);
d=unique(x+1,x+1+sign)-(x+1);
len+=abs(line[sign].r-line[sign].l);
pre=0;
for(int i=1;iprintf("%lld\n",len);
}return 0;
}
Poj1177 求矩形並的輪廓周長
題意 給出多個矩形,求這些矩形所覆蓋圖形的周長。可用線段樹來做,兩種方法 1 分別對x和y方向離散化後做線段樹,求出各方向上的輪廓長 2 對乙個方向上的座標進行離散化,用另一維進行掃瞄 1 覆蓋的線段長度 2 不相邊的線段數 3 該節點表示的區間兩端點是否被覆蓋 用於合併線段 code includ...
poj 1177 區間樹求矩形周長並
題意 在平面上給若干矩形,求它們的周長並。分析 用區間樹維護x軸上區間的一些覆蓋屬性。區間樹維護的是一些區間的性質,構造為build l,mid build mid,r 線段樹維護的是一些點的性質,構造為build l,mid build mid 1,r 區間樹經常被視為線段樹,但個人認為因為點線有...
POJ 1177 Picture 矩形周長並
題意很簡單,但是周長並比面積並又稍微麻煩了一些 這時候要開乙個numseg儲存豎邊的個數。再開lbd,rbd分別表示邊界,這樣是為了幫助刪除重合的邊 id sdj22251 prog subset lang c include include include include include incl...