横空出世!新型凸包!无限缩行!奇丑无比!首创“砖头凸包”!

这就是全新的凸包求法!只有6行!!!都缩成一砣屎了!!!咆哮一下!!

8.27更新:只有5行了!

void qhull (int l, int r, node a, node b, node c)
{
  if (l > r) return;
  int i = l - 1, j = r + 1, k, s = l, sw = 0, t = r, tw = 0; double d;
  for (k = l; k <= r; ++k) if ((d = x3p (p[k], a, b)) > 0) swap (p + (++i), p + k), d > sw ? s = i, sw = d : 0;
  for (k = r; k >= l; --k) if ((d = x3p (p[k], b, c)) > 0) swap (p + (--j), p + k), d > tw ? t = j, tw = d : 0;
  qhull (j, r, b, p[t], c), ch[++chtop] = b, qhull (l, i, a, p[s], b);
}

注意,这种写法是把凸包按顺时针排列,也就是维护右转。如果要维护左转,则最后一行的两个递归要交换一下顺序。

再次注意:这种写法是会把原点集打乱顺序的。如果不想打乱顺序,那么就设个idx把,反正graham的排序如果不想打乱也得设个idx。。

其实还有两个很简单的小函数没写:

#define qhc(i,j,k) ((j.x - i.x) * (k.y - i.y) - (j.y - i.y) * (k.x - i.x))
inline void swap (node *i, node *j){node t = *i; *i = *j; *j = t;}

qhc是求差积,即(j-i)X(k-i)。swap无须解释了吧。。

调用可能有些烦:

  for (l = 1, i = r = 2; i <= n; ++i) p[i].x < p[l].x ? l = i : 0, p[i].x > p[r].x ? r = i : 0;
  swap (p + 1, p + l), ch[++chtop] = p[1], qhull (2, n, p[1], p[r], p[1]);

缩行缩的自己都看不清了!!!

啊,用这个凸包写了poj1113,1A,好开心。。

#include 
#ifndef ONLINE_JUDGE
#include 
#endif
#include 


typedef struct {int x, y;} node;
#define maxn 1005


node ch[maxn];
int chtop = 0;
node p[maxn];


#define x3p(i,j,k) ((j.x - i.x) * (k.y - i.y) - (j.y - i.y) * (k.x - i.x))
inline void swap (node *i, node *j){node t = *i; *i = *j; *j = t;}


void qhull (int l, int r, node a, node b, node c)
{
  if (l > r) return;
  int i = l - 1, j = r + 1, k, s = l, sw = 0, t = r, tw = 0; double d;
  for (k = l; k <= r; ++k) if ((d = x3p (p[k], a, b)) > 0) swap (p + (++i), p + k), d > sw ? s = i, sw = d : 0;
  for (k = r; k >= l; --k) if ((d = x3p (p[k], b, c)) > 0) swap (p + (--j), p + k), d > tw ? t = j, tw = d : 0;
  qhull (j, r, b, p[t], c), ch[++chtop] = b, qhull (l, i, a, p[s], b);
}


int main()
{
  FILE *fin  = fopen ("1113.in" , "r");
  FILE *fout = fopen ("1113.out", "w");


  int n, l, r, i; double t = 0;


  fscanf (fin, "%d%d", &n, &l), t = 2 * 3.14151926 * l;
  for (i = 1; i <= n; ++i)
    fscanf (fin, "%d%d", &p[i].x, &p[i].y);
  for (i = l = 1, r = n; i <= n; ++i) p[i].x < p[l].x ? l = i : 0, p[i].x > p[r].x && i != 1 ? r = i : 0;
  swap (p + 1, p + l), ch[++chtop] = p[1], qhull (2, n, p[1], p[r], p[1]);


  for (i = 1, ch[++chtop] = ch[1]; i < chtop; ++i)
    t += sqrt ((ch[i + 1].x - ch[i].x) * (ch[i + 1].x - ch[i].x) + (ch[i + 1].y - ch[i].y) * (ch[i + 1].y - ch[i].y));
  
  fprintf (fout, "%.0f\n", t);
  fclose (fin);
  fclose (fout);
  return 0;
}




你可能感兴趣的:(file,struct,c)