hdu 3642
至少有2個以上不同地點才存在寶藏.即3個以上的空間立體交叉覆蓋出的體積,覆蓋3次及以上
x y z
包括整個庫,意思就是給出頂點,觀察樣例知道是左上和右下的座標z<=500
.那麼掃瞄法求出平面的面積,在處理題目給出的每一層.求的體積
x
用來離散化後作為橫軸建線段樹,z
軸存下來列舉每乙個層.x軸座標
離散化後要去重,z軸座標
要用來列舉所以也要去重.
開始列舉每一層的z軸高度
,篩選出該層的所有點來求面積,將x軸上的橫邊
按照y軸的高度
來排序(掃瞄線標準做法).
建立線段樹開始掃瞄,
add
表示該區間被覆蓋的次數len1
表示該區間被覆蓋次數為1的長度len2
表示該區間被覆蓋次數為2的長度len3
表示該區間被覆蓋次數》=3的長度
#include #include #include using namespace std;
const int n = 2005;
struct edge
edge(int left,int right,int height,int flag)
bool operator<(const edge& temp)const
}e[n<<1];
struct node q[n<<3];//?
int x[n<<1], z[n<<1];
#define ls i<<1
#define rs i<<1|1
struct point
point(int tx,int ty,int tz)
}a[n<<1];
void build(int i,int l,int r)
void pushup(int i)
else if (q[i].add == 2)
else if (q[i].add == 1)
else
}void update(int i, int l,int r,int val)
int mid = (q[i].l + q[i].r) >> 1;
if (r <= mid) update(ls,l,r,val);
else if (l > mid) update(rs,l,r,val);
else
pushup(i);
}int main()
printf("case %d: ",++count);
if (n < 3)
sort(x,x+totx);
sort(z,z+totz); // x和z座標從小到大排個序
// 去重,讓每乙個座標都對應乙個值
totx = unique(x, x + totx) - x;
totz = unique(z, z + totz) - z;
long long ansxyz = 0;
for (int i = 0; i < totz-1; i++)
}sort(e,e+k); // 根據y軸的值來排序,xy平面上的高度
memset(q,0,sizeof q); //清空線段樹
build(1,0,totx-1);// x的範圍[0,totx-1]
long long ansxy = 0;
// 掃瞄線開始掃瞄
for (int j = 0; j < k - 1; j++)
ansxyz += (long long)ansxy * (long long)(z[i+1] - z[i]); //面積*z軸高度=體積
} printf("%i64d\n",ansxyz);
} return 0;
}
hdu 3642 覆蓋3次以上體積
題目大意 給你n個立方體,求相交區域大於等於三次的體積和。這題需要前面兩題的知識 體積並面積交 對於面積交,另外建立len2陣列表示覆蓋2次的面積,len3陣列表示覆蓋3次及以上的面積 對於體積並,離散化x座標是為了建樹,離散化z座標是為了節省時間。對於所有的體積範圍進行面積交之和即為所求體積 in...
HDU 1255 掃瞄線求二次覆蓋的面積 線段樹
hdu 1255 add 1說明覆蓋 2次可以直接計算覆蓋長度q i len2 x q i r 1 x q i l 如果是葉節點就q i len2 0add 1說明當前節點區間被覆蓋了一次,想要求得覆蓋 2次的區間,此時還要考慮子區間被覆蓋的情況 加上子區間被覆蓋 1次的區間長度,累加起來就被覆蓋 ...
覆蓋的面積 HDU 1255 掃瞄線 二次覆蓋
includeusing namespace std define ll long long const int maxn 1010 int n double x maxn 1 struct edge edge double a,double b,double c,int d l a r b h c...