#include using namespace std;
struct point
};typedef point vector;
int cross(vector a, vector b)
vector operator +(vector a, vector b)//
vector operator -(point a, point b)//
vector operator *(vector a, double p)//
vector operator /(vector a, double p)//
bool operator
const double eps = 1e-10;
int dcmp(double x)//
bool operator ==(const point &a, const point &b)//
double dot(vector a, vector b)//
int dist2(const point &a, const point &b)
vectorconvexhull(vector& p)
int k = m;
for (int i = n - 2; i >= 0; i--)
if (n > 1) m--;
ch.resize(m);
return ch;
}int getmaxdirmater(vector&points)
v = (v + 1) % n;
} }return ans;
}int t, n, kase, x, y, z;
int main(int argc, char const *argv)
printf("%d\n", getmaxdirmater(points));
} return 0;
}
我們將乙個多邊形上任意兩點間的距離的最大值定義為多邊形的直徑。 確定這個直徑的點對數可能多於一對。 事實上, 對於擁有
n個頂點的多邊形, 就可能有
n對「直徑點對」存在。
乙個多邊形直徑的簡單例子如左圖所示。 直徑點對在圖中顯示為被平行線穿過的黑點 (紅色的一對平行線). 直徑用淺藍色高亮顯示。
顯然, 確定乙個凸多邊形
p直徑的點對不可能在多邊形
p內部。 故搜尋應該在邊界上進行。 事實上, 由於直徑是由多邊形的平行切線的最遠距離決定的, 所以我們只需要查詢對踵點。 shamos (1978) 提供了乙個
o(n)
時間複雜度計算n點凸包對踵點對的演算法。直徑通過遍歷頂點列表, 得到最大距離即可。 如下是2023年發表於 preparata 和 shamos 文章中的 shamos 演算法的偽**。
輸入是乙個多邊形
p=.
begin此處p0:=pn;
q:=next[p];
while (area(p,next[p],next[q]) > area(p,next[p],q)) do
q:=next[q];
q0:=q;
while (q != p0) do
begin
p:=next[p];
print(p,q);
while (area(p,next[p],next[q]) > area(p,next[p],q) do
begin
q:=next[q];
if ((p,q) != (q0,p0)) then print(p,q)
else return
end;
if (area(p,next[p],next[q]) = area(p,next[p],q)) then
if ((p,q) != (q0,p0)) then print(p,next[q])
else print(next[p],q)
endend.
print(p,q)
表示將
(p,q)
作為乙個對踵點對輸出,area(p,q,r)
表示三角形
pqr的有向面積。
雖然直觀上看這個過程與常規旋轉卡殼演算法不同, 但他們在本質上是相同的, 並且避免了所有角度的計算。
如下是乙個更直觀的演算法:
計算多邊形 y 方向上的端點。 我們稱之為 ymin 和 ymax 。
通過 ymin 和 ymax 構造兩條水平切線。 由於他們已經是一對對踵點, 計算他們之間的距離並維護為乙個當前最大值。
同時旋轉兩條線直到其中一條與多邊形的一條邊重合。
乙個新的對踵點對此時產生。 計算新的距離, 並和當前最大值比較, 大於當前最大值則更新。
重複步驟3和步驟4的過程直到再次產生對踵點對 (ymin,ymax) 。
輸出確定最大直徑的對踵點對。
至此, 上述的過程(偽**中的)顯得十分有用, 我們可以從對踵點對中得到其他的資訊, 如多邊形的寬度 。
來自:其實就是列舉每乙個可能的頂點,用旋轉卡殼的方法算出每乙個點的最遠距離,求最大值即可
LA 4728 旋轉卡殼 Squares
題意 求平面上的最遠點對距離的平方。分析 對於這個資料量列舉肯定是要超時的。首先這兩個點一定是在凸包上的,所以可以列舉凸包上的點,因為凸包上的點要比原來的點會少很多,可最壞情況下的時間複雜度也是o n2 於是就有了旋轉卡殼。可以想象有兩條平行直線緊緊地夾住這個凸包,那直線上的點就是對踵點對。對踵點對...
LA 4728凸包演算法 旋轉卡殼的直徑
1 la 4728 2凸包演算法 旋轉卡殼的直徑 3沒有其他技巧,可作為模板運用 4注意operator 中精度的處理,不然會出錯5 6 include 7 include 8 include 9 include 10 include 11 include 12 include 13 include...
旋轉卡殼 Rotating Calipers
上週做了一些凸包等計算幾何的問題,感覺挺有意思的,想好好研究一下,發現乙個推薦的英文 雖然沒有多少,但是還是想試著通過自己做題的領悟加上6級水平的英語來翻譯一下,請批評指正。原文 在1978年,m.i.shamos s 博士 計算幾何 標誌著這一領域在電腦科學中的誕生。這在他發表的成果中是乙個尋找凸...