旋轉卡殼 x Beauty Contest

2021-09-07 10:38:20 字數 1827 閱讀 3034

旋轉卡qia殼ke好難理解啊。。其實是蒟蒻太菜了

本題不難看出是求凸包直徑

旋轉卡殼演算法最基本的用法也是求凸包直徑

我們可以把它當作用兩根平行的小棍夾緊凸包

然後旋轉凸包一周 小棍間最大的距離

對於乙個凸包 按一般求法排序很容易能得到最左邊的點和最右邊的點 它們之間的距離就是讓小棍和y軸平行時的間距

對於任意方向上使間距最大的點對叫對踵點對

現在考慮用這兩個點推出下一組點

借用乙個經典的圖

很直觀地能看出這個圖中 點到底邊的距離是乙個單峰函式

而已求出點對的下一組點對 不是一端的點順時針轉乙個 就是另一端的點轉

另外這裡要應用到乙個小技巧

就是兩向量叉積的模長 等於這兩個向量座標的點與原點圍成的三角形面積

附上**

#include

#include

#include

#include

using

namespace std;

const

int n =

5e4+5;

/*凸包直徑

*/struct nodenode[n]

, stk[n]

;int top, n, target;

long

long ans;

inline node operator-(

const node& x,

const node& y);}

inline

bool

rule

(const node& x,

const node& y)

inline

long

long

dis(

const node& x)

inline

long

long

cross

(const node& x,

const node& y)

inline

void

print

(node x)

inline

void

andrew()

target = top;

for(

int i = n -

1; i >=1;

--i)

if(top >1)

--top;

//非常非常重要!回來的時候會多算乙個起點!

}inline

void

rotating_caliper()

if(n ==3)

ans =-1

; stk[0]

= stk[top]

; stk[top +1]

= stk[1]

; target =3;

for(

int i =

1; i <= top;

++i)if(

dis(stk[i]

- stk[target]

)> ans)}}

intmain()

sort

(node +

1, node + n +

1, rule)

;andrew()

;rotating_caliper()

;printf

("%lld"

, ans)

;return0;

}

旋轉卡殼 Rotating Calipers

上週做了一些凸包等計算幾何的問題,感覺挺有意思的,想好好研究一下,發現乙個推薦的英文 雖然沒有多少,但是還是想試著通過自己做題的領悟加上6級水平的英語來翻譯一下,請批評指正。原文 在1978年,m.i.shamos s 博士 計算幾何 標誌著這一領域在電腦科學中的誕生。這在他發表的成果中是乙個尋找凸...

旋轉卡殼演算法

直接按照這個描述可以實現旋轉卡殼演算法,但是 肯定相當冗長。逆向思考,如果qa,qb是凸包上最遠兩點,必然可以分別過qa,qb畫出一對平行線。通過旋轉這對平行線,我們可以讓它和凸包上的一條邊重合,如圖中藍色直線,可以注意到,qa是凸包上離p和qb所在直線最遠的點。於是我們的思路就是列舉凸包上的所有邊...

模板 旋轉卡殼

link 模板乙個。其實感覺說是求凸包的直徑倒不如說是求平面內最遠點對,畢竟它的輸入沒保證是個凸包,自己還要再求一遍啊 旋轉卡殼的思想十分優雅易懂,就是先證明平面內最近點對一定是凸包上兩點,再根據這個結論,列舉每一條邊的同時找出離線段最遠的點並更新答案即可。為了盡可能地降低找點的複雜度,對問題進行分...