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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二维凸包 Graham's Scan

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二维凸包 Graham's Scan 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

凸包是啥??

凸包就是:

給定二維平面上的點集,凸包就是將最外層的點連接起來構成的凸多邊型,它能包含點集中所有的點。


外層的紅線 就是凸包


一般題目會讓你求利用最外層凸包的一些性質如下面這道題

來看一道模板題:HDU - 1348



本題題目就是要求盡可能少的圍墻周長 圍墻內的城堡是多邊形的 而圍墻還要和城堡相隔l距離

可證 實質周長其實就是 城堡的凸包周長 + 以l為半徑的周長之和?

由于多邊形城堡 盡可能少的包圍他其實就是凸包周長 而在凸包的拐角處 要相隔l距離 所以變成了一個圓弧

把圓弧加起來就是圓的周長?

n邊形的內角和公式 :(n-2)*180

n變形外角永遠是360度

所以 可以列式 n×360 - (n-2)×180 -90×n×2 = 360° (n個角 減去內角 在減去多余的90° 畫個圖就能得到)

所以多出來的那些空間可知就是一個360°的整圓


關于這個方法就是先取左下點為基準點?

?然后 對其他點 按照從基準點的x軸逆時針方向射出的極角 掃過的順序排序?


然后再對其中的每前后三個點進行叉乘操作

?

?如果我們以逆時針方向遍歷所有點

n,m,l三個點 

n為起點 向m和l點做兩個向量分別是向量a,向量b

向量a*b<0 說明 a在 b的逆時針方向  即是說 m點在l點里面,左邊 若選凸包 我們舍棄a的終點m 而選取b的終點?

若叉乘結果>0說明a在b的順時針方向 也就是 m在l的外邊 右邊

最終將保存下來的點 按順序遍歷求兩點之間的線段長度就可以了


code

#include<bits/stdc++.h>using namespace std; typedef long long ll; const int maxn = 1010; const double pi = acos(-1.0);// 得到PI struct node {double x,y; }p[1010],P[1010];//P內存儲凸包內的店 int t,tot,N; double L; double X(node a,node b,node c) {return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); }// 計算叉積 double len(node a,node b) {return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y)); }//兩點之間距離公式 bool cmp(node b,node c) {double pp = X(p[1],b,c);if(pp<0)return 0;else if(pp>0)return 1;else if(pp==0&&len(p[1],b)<len(p[1],c))return 1;else return 0; }//掃描排序 int main() {scanf("%d",&t);for(int cas = 1;cas<=t;cas++){if(cas!=1)puts("");scanf("%d%lf",&N,&L);for(int i=1;i<=N;i++)scanf("%lf%lf",&p[i].x,&p[i].y);double ans = pi*2.0*L;for(int i=2;i<=N;i++){if(p[1].y>p[i].y)swap(p[1],p[i]);else if(p[1].y==p[i].y&&p[1].x>p[i].x)swap(p[1],p[i]);}//找基準點sort(p+2,p+1+N,cmp);P[1]=p[1];P[2]=p[2];tot=2;for(int i=3;i<=N;i++){while(tot>1&&X(P[tot-1],P[tot],p[i])<=0)tot--;tot++;P[tot] = p[i];}//篩選點for(int i=1;i<tot;i++){ans+=len(P[i],P[i+1]);}//圍圈求和ans+=len(P[1],P[tot]);printf("%.0lf\n",ans);}return 0; }


總結

以上是生活随笔為你收集整理的二维凸包 Graham's Scan的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。