这就是全新的凸包求法!只有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;}
调用可能有些烦:
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;
}