傳送門
題面的定義顯然就是求乙個點集a,b
a,ba,
b的閔可夫斯基和的凸包的面積的兩倍。
那麼這道題就是閔可夫斯基和的模板了。
所謂閔可夫斯基和,即給你兩個點集a,b
a,ba,
b,求乙個點集c
=c=\
c=,c
cc即點集a,b
a,ba,
b的閔可夫斯基和。
對於求閔可夫斯基和,我的理解是:我們考慮先求a,b
a,ba,
b的凸包,閔可夫斯基和的凸包肯定是由a,b
a,ba,
b凸包上的點加起來的,我們對於a,b
a,ba,
b的兩個凸包,存的時候按點座標從最左下角然後逆時針方向存。
因為a ,b
a,ba,
b兩個凸包的點是按逆時針存的,所以我們通過瞪眼法可以發現,如果把閔可夫斯基和的凸包上的點用乙個n×m
n\times m
n×m的矩陣表示(n,
m(n,m
(n,m
是凸包a,b
a,ba,
b上點的個數)
)),(i,
j(i,j
(i,j
表示凸包a
aa上的第i
ii個點加上凸包b
bb上的第j
jj個點)
))那麼閔可夫斯基和的凸包上的點是從左下角(1,
1)
(1,1)
(1,1
)到右上角(n,
m)
(n,m)
(n,m
)的一條路徑(
((需要意會)
))。然後我們兩個指標分別指向a,b
a,ba,
b的兩個凸包,每次取出兩個點比較,利用叉積看誰往外偏的多就選誰。
覺得還是**好理解,反正我是直接看**看懂的:
void
minkowski()
while
(i1<=cnt1)
while
(i2<=cnt2)
}
tu[
0/1]
tu[0/1]
tu[0/1
]是a,
ba,b
a,b的兩個凸包上的點,用va,
vb
va,vb
va,v
b存凸包上點變化的向量,那麼後面通過向量加法就可以表示凸包上點的變化。
剩下就是凸包,叉積等板子,最後求面積的話其實不用再求一遍閔可夫斯基和的凸包(
((我無聊又求了一遍)
)),如果求的話作用就是去掉凸包上三點共線的點:
#include
#define ts cout<<"ok"<#define ll long long
#define hh puts("")
using
namespace std;
int n,m,st[
100005
],top,cnt1,cnt2,cnt,tot;
ll res;
double eps=
1e-8
;struct pointa[
100005
],b[
100005
],tu[2]
[100005
],va[
100005
],vb[
100005
],ans[
200005
],ed[
200005];
inline
intread()
while
(isdigit
(ch)
)return ret*ff;
}point operator
+(point a,point b);}
point operator
-(point a,point b);}
inline
bool
cmp(point a,point b)
inline
double
getk
(point a,point b)
inline ll cross
(point a,point b)
void
graham
(point t,
int id,
int all)
}for
(int i=
1;i<=top;i++
) tu[id]
[++cnt]
=t[st[i]];
top=0;
for(
int i=
1;i<=all;i++)}
for(
int i=top-
1;i>=
2;i--
) tu[id]
[++cnt]
=t[st[i]];
}void
minkowski()
while
(i1<=cnt1)
while
(i2<=cnt2)
}signed
main()
}for
(int i=
1;i<=top;i++
) ed[
++cnt]
=ans[st[i]];
top=0;
for(
int i=
1;i<=tot;i++)}
for(
int i=top-
1;i>=
2;i--
) ed[
++cnt]
=ans[st[i]];
for(
int i=
1;i) res+
=cross
(ed[i]
,ed[i+1]
);res+
=cross
(ed[cnt]
,ed[1]
);printf
("%lld"
,res)
;return0;
}
bzoj 2564 集合的面積
對於乙個平面上點的集合p 定義集合p的面積f p 為點集p的凸包的面積。對於兩個點集a和b,定義集合的和為 a b 現在給定乙個n個點的集合a和乙個m個點的集合b,求2f a b 第一行包含用空格隔開的兩個整數,分別為n 和m 第二行包含n個不同的數對,表示a集合中的n個點的座標 第三行包含m個不同...
bzoj 2734 集合選數
構造矩陣 1 3 9 27 2 6 18 54 4 12 36 108 每個數是上面的數乘2,左面的數乘3。這樣進行狀壓dp就是相鄰的格仔不能選的方案數。如何判斷乙個二進位制數沒有兩個連續的1?x x 1 0 如果有的數沒有出現過,就以它為左上角元素再構造乙個矩陣。這是怎麼想到的?include i...
BZOJ2734 集合選數
集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 3x 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題 對於任意乙個正整數 n 100000,如何求出 的滿足上述約束條件的子集的個數 只需輸出對 1,000,...