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