问题: 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。
这个算法是由数学大师葛立恒Graham发明的,他曾经是美国数学学会AMS主席、ATT 首席科学家... (see http://www.doc88.com/p-08332037489.html)
模板:see http://kmplayer.iteye.com/blog/604405
#include <iostream> #include <algorithm> using namespace std; class point { public: double x, y; point(){x = 0; y = 0;} }; bool mult(point sp, point ep, point op) { cout << "checking (" << sp.x << "," << sp.y <<"),(" << ep.x << "," << ep.y << "),(" << op.x << "," << op.y<<") : " ; bool tu = (sp.x - op.x)*(ep.y - op.y) >= (ep.x - op.x)*(sp.y - op.y); cout << tu << endl; return tu; } bool operator<(const point &l, const point &r) { return l.y < r.y || ((l.y == r.y) && (l.x < r.x)); } void print(point res[], int n) { cout << "stack : " ; for(int i = 0; i <= n; i++) { cout << "(" << res[i].x << ", " << res[i].y << "),"; } cout << endl; } int graham(point pnt[], int n, point res[]) { int i, len, k = 0, top = 1; sort(pnt, pnt + n); if (n == 0) { return 0; } res[0] = pnt[0]; if (n == 1) { return 1; } res[1] = pnt[1]; if (n == 2) { return 2; } res[2] = pnt[2]; for(int i = 2; i < n; i++) { while(top && mult(pnt[i], res[top], res[top-1])) { cout << "poping point (" << res[top].x << ", " << res[top].y << ")" << endl; top --; print(res, top); } cout << "pusing point (" << pnt[i].x << ", " << pnt[i].y << ")" << endl; res[++top] = pnt[i]; print(res, top); } print(res, top); cout << "-----" << endl; len = top; res[++top] = pnt[n-2]; print(res, top); for(i = n-3; i>=0; i--) { while(top != len && mult(pnt[i], res[top], res[top-1])) { cout << "poping point (" << res[top].x << ", " << res[top].y << ")" << endl; top--; print(res, top); } cout << "pusing point (" << pnt[i].x << ", " << pnt[i].y << ")" << endl; res[++top] = pnt[i]; print(res, top); } return top; } point pnt[1000]; point res[1000]; int n = 0; int main() { double x,y; while(cin >> x >> y) { pnt[n].x = x; pnt[n].y = y; n++; } int num = graham(pnt, n, res); print(res, num); }
/home/a/j/nomad2:cat input 1 1 2 2 3 2.5 4 1 /home/a/j/nomad2:cat input |./a.out checking (2,2),(4,1),(1,1) : 0 pusing point (2, 2) stack : (1, 1),(4, 1),(2, 2), checking (3,2.5),(2,2),(4,1) : 1 poping point (2, 2) stack : (1, 1),(4, 1), checking (3,2.5),(4,1),(1,1) : 0 pusing point (3, 2.5) stack : (1, 1),(4, 1),(3, 2.5), stack : (1, 1),(4, 1),(3, 2.5), ----- stack : (1, 1),(4, 1),(3, 2.5),(2, 2), checking (4,1),(2,2),(3,2.5) : 0 pusing point (4, 1) stack : (1, 1),(4, 1),(3, 2.5),(2, 2),(4, 1), checking (1,1),(4,1),(2,2) : 1 poping point (4, 1) stack : (1, 1),(4, 1),(3, 2.5),(2, 2), checking (1,1),(2,2),(3,2.5) : 0 pusing point (1, 1) stack : (1, 1),(4, 1),(3, 2.5),(2, 2),(1, 1), stack : (1, 1),(4, 1),(3, 2.5),(2, 2),(1, 1),
POJ 1113