什麼是凸包?ios
個人理解就是,圖形任意兩點的連線都沒有在圖形外部。數組
問題:給定點集,怎麼求出凸包的邊界點呢???spa
第一步:給這些點按照X的從大到小進行排序,若是X相同的按照Y再排序。3d
第二步:把X最小的和最大的連起來,他們必爲凸包的邊界點。blog
第三步:把平面區域分爲兩個部分,分別在上面和下面去找面積最大的三角形(面積最大包括的點也就越多嘛,因此適合當凸包的邊界點)排序
那面積怎麼求呢?遞歸
求三角形的面積,假設三個點,A(x1,y1),B(x2,y2), C(x3,y3),如下行列式對於平面上任意三角形, 求解面積都很方便, 所得結果是三角形ABC面積的兩倍,A->B->C爲順時針順序時,該值爲正,,反之則爲負。ci
第四步:進行遞歸,把三角形左邊那個邊做爲底邊又去找面積最大的三角形,同理右邊,下面也同樣。it
上代碼!!!io
#include <iostream> using namespace std; #include <algorithm> #include <stdlib.h> #define N 10000 int n = 0; struct POINT { int x, y; }p[N],ans[N]; int visit[N],mark[N]; int Djudge(POINT a1, POINT a2, POINT a3) { int calculate = a1.x*a2.y + a3.x*a1.y + a2.x*a3.y - a3.x*a2.y - a2.x*a1.y - a1.x*a3.y; return calculate; } bool cmpxy(const POINT a, const POINT b) //按x軸排序,若是x相同,按y軸排序 { if (a.x != b.x) return a.x < b.x; else return a.y < b.y; } void DealLeft(int first, int last) { int max = 0, index = -1; int i = first; if (first < last) { for (i = first+1; i < last; i++) //注意兩端,對於first和last,不必再進行計算 { int calcu = Djudge(p[first], p[i], p[last]); if (calcu == 0) { visit[i] = 1; } // if (calcu > max) { max = calcu; index = i; } } } else { for (i-1; i >last; i--) //若是first>last,重複上述過程,注意這裏下界不是0. { int calcu = Djudge(p[first], p[i], p[last]); if (calcu == 0) {visit[i] = 1;} // if (calcu > max) { max = calcu; index = i; } } } if (index != -1) { visit[index] = 1; //對取到的點進行標註 DealLeft(first, index); DealLeft(index, last);//分治的部分 } } int main() { cout<<"請輸入點數:"<<endl; cin >> n; cout<<"請輸入點的座標:"<<endl; for (int i = 0; i < n; i++) { cin >> p[i].x >> p[i].y; visit[i] = 0; } visit[0] = 1; visit[n - 1] = 1; sort(p, p + n, cmpxy); DealLeft(0, n - 1); //查找上凸包; DealLeft(n - 1, 0); //查找下凸包; int t = 0; for (int i = 0; i < n; i++) { if (visit[i] == 1) { ans[t].x = p[i].x; ans[t].y = p[i].y; t++; } } //順時針輸出 mark[0] = mark[t - 1] = 1; //數組mark避免重複檢查下降效率 for (int i = 1; i < t - 1; i++) { mark[i] = 0; } cout<<"凸包點的座標:"<<endl; cout << ans[0].x << " " <<ans[0].y<< endl; for (int i =1; i < t-1; i++) { int d = Djudge(ans[0], ans[t-1], ans[i]); if (d >= 0) { cout << ans[i].x << " " << ans[i].y << endl; mark[i] = 1; } } cout << ans[t - 1].x << " " << ans[t - 1].y << endl; for (int i = 1; i < t; i++) { if (mark[i] != 1) { int d = Djudge(ans[0], ans[t - 1], ans[i]); if (d < 0) { cout << ans[i].x << " " << ans[i].y << endl; } } } return 0; }