日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

旋转卡壳求凸包直径

發(fā)布時(shí)間:2024/4/17 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 旋转卡壳求凸包直径 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

思路

直徑即最長的兩點(diǎn)的距離
枚舉凸包上的所有邊,對每一條邊找出凸包上離該邊最遠(yuǎn)的頂點(diǎn)(用叉積),計(jì)算這個(gè)頂點(diǎn)到該邊兩個(gè)端點(diǎn)的距離,并記錄最大的值。但是注意到當(dāng)我們逆時(shí)針枚舉邊的時(shí)候,最遠(yuǎn)點(diǎn)的變化也是逆時(shí)針的,這樣就可以不用從頭計(jì)算最遠(yuǎn)點(diǎn),而可以緊接著上一次的最遠(yuǎn)點(diǎn)繼續(xù)計(jì)算。于是我們得到了O(n)的算法。

復(fù)制的圖


常數(shù)巨大的丑陋代碼

# include <stdio.h> # include <stdlib.h> # include <iostream> # include <string.h> # include <math.h> # include <algorithm> # define RG register # define IL inline # define ll long long # define mem(a, b) memset(a, b, sizeof(a)) # define Min(a, b) (((a) > (b)) ? (b) : (a)) # define Max(a, b) (((a) < (b)) ? (b) : (a)) # define Sqr(a) ((a) * (a)) using namespace std;const int MAXN = 50001; int n, top = 2; struct Point{int x, y, len; } p[MAXN], Point_A, s[MAXN]; //最左下的點(diǎn) //求叉積(向量ab,向量ac) IL int Cross(Point a, Point b, Point c){return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); } //極角排序 IL int Dis(Point a, Point b){return Sqr(a.x - b.x) + Sqr(a.y - b.y); }IL bool Cmp(Point a, Point b){RG int x = Cross(Point_A, a, b);if(x > 0) return 1;else if(x < 0) return 0;a.len = Dis(Point_A, a);b.len = Dis(Point_A, b);return a.len < b.len; }IL void Find(){Point_A = p[1]; RG int temp = 0;for(RG int i = 2; i <= n; i++)if((Point_A.y == p[i].y && Point_A.x > p[i].x) || Point_A.y > p[i].y)Point_A = p[i], temp = i;p[temp] = p[1]; p[1] = Point_A; }IL void Graham(){Find();sort(p + 2, p + n + 1, Cmp);p[++n] = s[0] = p[1]; s[1] = p[2]; s[2] = p[3];for(RG int i = 4; i < n; i++){while(Cross(s[top - 1], s[top], p[i]) <= 0 && top) top--;s[++top] = p[i];}s[++top] = p[n]; }IL int Rot_Cover(){RG int q = 1, ans = 0;for(RG int i = 0; i < top; i++){while(Cross(s[i], s[i + 1], s[q]) < Cross(s[i], s[i + 1], s[q + 1])) q = (q + 1) % top;//等底的情況下,叉積越大即面積越大離該點(diǎn)越遠(yuǎn) ans = Max(ans, Dis(s[i], s[q]));ans = Max(ans, Dis(s[i + 1], s[q]));//判斷邊平行的情況 }return ans; }int main(){scanf("%d", &n);for(RG int i = 1; i <= n; i++)scanf("%d%d", &p[i].x, &p[i].y);if(n == 2) return !printf("%d\n", Dis(p[1], p[2]));Graham();printf("%d\n", Rot_Cover());return 0; }

裸題 Beauty Contest POJ - 2187

轉(zhuǎn)載于:https://www.cnblogs.com/cjoieryl/p/8206403.html

總結(jié)

以上是生活随笔為你收集整理的旋转卡壳求凸包直径的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。