凸包求法

来源:互联网 发布:用itunes安装软件 编辑:程序博客网 时间:2024/04/30 10:36
#include <iostream>#include <cmath>using namespace std;struct POINT { int x, y; int flag; // 表示是否在连线内部,在为0};POINT list[500], pk;int stack[500], top, k, rightnum;void swap(POINT &a, POINT &b){ POINT t; t = a; a = b; b = t;}int CrossProd(POINT p0, POINT p1, POINT p2){ return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);}int comp(const void *pp1, const void *pp2){ //int t; POINT *p1 = (POINT*)pp1, *p2 = (POINT*)pp2; return CrossProd(list[0], *p1, *p2)*(-1);}void select(int n, int &num){ POINT p1, p2; int t, i, j, f; for (i = 1; i < n; i++) {  f = 0;  p1 = list[i];  if (p1.flag)  {   for (j = i + 1; j < n; j++)   {    p2 = list[j];    if (p2.flag)    {     t = CrossProd(list[0], p1, p2);     if (t == 0)     {      if ((p1.x - list[0].x) * (p1.x - list[0].x) + (p1.y - list[0].y) *(p1.y - list[0].y) \       < (p2.x - list[0].x) * (p2.x - list[0].x) + (p2.y - list[0].y) *(p2.y - list[0].y))      {       list[i].flag = 0;      }      else list[j].flag = 0;     }    }   }  } } i = 1; for (j = 1; j < n; j++) {  if (list[j].flag == 1)  {   list[i] = list[j];   i++;  } } num = i - 1; qsort(list + 1, num, sizeof(POINT), comp);}int init(int n){ int i, num; for (i = 0; i < n; i++) {  cin >> list[i].x >> list[i].y;  list[i].flag = 1;  if ((list[i].y < list[0].y) || (list[i].y == list[0].y) && (list[i].x < list[0].x))  {   swap(list[0], list[i]);  } } select(n, num); return num + 1;}void graham(int n){ int i; if (n == 1) cout << "(" << list[0].x << ", " << list[0].y << ")" << endl; if (n == 2) cout << "(" << list[0].x << ", " << list[0].y << ")" \  "(" << list[1].x << ", " << list[1].y << ")" << endl; if (n > 2) {  for (i = 0; i <= 2; i++) stack[i] = i;  top = 2;  for (i = 3; i <= n-1; i++)  {   while (CrossProd(list[stack[top-1]], list[stack[top]], list[i]) <= 0)    top--;   top++;   stack[top] = i;  }  for (i = 0; i <= top; i++) cout << "(" << list[stack[i]].x << ", " << list[stack[i]].y << ")";  cout << endl; }}void Chain(int n, int LR) // LR=1生成右链,LR=0生成左链{ int m = 0, i, t; POINT pm; stack[0] = 0; top = 0; while (m != k) {  pm = pk;  m = k;  for (i = 1; i < n; i++)  {   t = CrossProd(list[stack[top]], list[i], pm);   if ((t > 0 && LR==1) || (t < 0 && LR == 0) ||\    (t == 0) && ((list[i].x - list[stack[top]].x) * (list[i].x - list[stack[top]].x) \    + (list[i].y - list[stack[top]].y)*(list[i].y - list[stack[top]].y)    > (pm.x - list[stack[top]].x) * (pm.x - list[stack[top]].x) \    + (pm.y - list[stack[top]].y) * (pm.y - list[stack[top]].y)))   {    pm = list[i];    m = i;   }  }  top ++;  stack[top] = m; } if (LR == 1) {  for (i = 0; i <= top; i++)  {   cout << "(" <<list[stack[i]].x << ", " << list[stack[i]].y << ")";  } } else {  for (i = top - 1; i > 0; i--)  {   cout << "(" <<list[stack[i]].x << ", " << list[stack[i]].y << ")";  }  cout << endl; }}void init2(int n){ int i; for (i = 0; i < n; i++) {  cin >> list[i].x >> list[i].y;  if (i == 0)  {   pk = list[0];   k = 0;  }  if ((list[i].y < list[0].y) || (list[i].y == list[0].y) && (list[i].x < list[0].x))   swap(list[0], list[i]);  if ((list[i].y > pk.y) || (list[i].y == pk.y) && (list[i].x > pk.x))  {   pk = list[i];   k = i;  } }}void Jarvis(int n){ if (n == 1) cout << "(" << list[0].x << ", " << list[0].y << ")" << endl; if (n == 2) cout << "(" << list[0].x << ", " << list[0].y << ")" \  "(" << list[1].x << ", " << list[1].y << ")" << endl; if (n > 2) {  Chain(n, 1);  Chain(n, 0); }}int main(){ int count = 0, n, num; while (cin >> n) {  if (n == 0) break;  count++;  cout << "set" << count << ":\n";  cout << "graham...(\n)";  num = init(n);  graham(num);  cout << "Jarvis...(\n)";  init2(n);  Jarvis(n); } return 0;}

原创粉丝点击