【计算几何小结】

          貌似好久没写总结了,都快不会写了。

          懒得分成几篇了,就一起挤一挤吧。


          另外, 这里有分开写的

         http://blog.csdn.net/huyuncong?viewmode=contents

                 哈哈!

          


初步的叉积:

          貌似最近才分清楚谁叉谁是正,以前都是推得=.=;

          最好还是模块化,一般很多情况都是只要调用两个参数,但是一般还是写成四个参数的,这样还是有好处的。


int cross(point a, point b, point c, point d)
{
	int x1 = b.x - a.x, y1 = b.y - a.y;
	int x2 = d.x - c.x, y2 = d.y - c.y;
	return x1 * y2 - x2 * y1;
}

          有时候也会写成这个样子, 只要确定不需要求面积的话...... 

          至少外面就不要判精度了


int cross2(point a, point b, point c, point d)
{
	double x1 = b.x - a.x, y1 = b.y - a.y;
	double x2 = d.x - c.x, y2 = d.y - c.y;
	double k = x1 * y2 - x2 * y1;
	if (k > eps) return 1; 
	else if (k < -eps) return -1;
	else return 0; 
}

         叉积的线段相交, 排斥试验也是必不可少的=.=(这样就丑死了)


bool checkpoint(point a, point b, point c, point d)
{
	if (max(a.x, b.x) >= min(c.x, d.x)
	   &max(a.y, b.y) >= min(c.y, d.y)
	   &max(c.x, d.x) >= min(a.x, b.x)
	   &max(c.y, d.y) >= min(a.y, b.y)
	   &cross(a, b, a, c) * cross(a, b, a, d)<= 0
	   &cross(d, c, d, a) * cross(d, c, d, b)<= 0)
	return true; else return false;
}

         如果要用解析流表示直线的话.......

line getline(point s, point t)
{
	line gl;
	if (s.x == t.x) gl.b = 0, gl.a = 1, gl.c = - s.x;
	else if (s.y == t.y) gl.b = 1, gl.a = 0, gl.c = - s.y;
	else gl.a = 1, gl.b = (s.x - t.x) / (t.y - s.y), gl.c = -(s.x + gl.b * s.y);
    return gl;
}

point findpoint(line g1, line g2)
{
    point p;
    p.y = - (g1.c - g2.c) / (g1.b - g2.b);
    p.x = - (g1.b * p.y + g1.c);
    return p;
}

        这还是归一化之后的,而且外面还有大片大片的特殊情况;

 

         当然, 还是射影坐标系方便, 表示直线时就没有各种特殊情况了。

         http://wenku.baidu.com/view/9f9a78c55fbfc77da269b172.html


line getline(point a, point b)
{
	line g;
	g.x = a.y * b.z - a.z * b.y;
	g.y = a.z * b.x - a.x * b.z;
	g.z = a.x * b.y - a.y * b.x;
	double low = sqrt(sqr(g.x) + sqr(g.y));
	g.x /= low; g.y /= low; g.z /= low;
	return g;
}

point getpoint(line a, line b)
{
	point g;
	g.x = a.y * b.z - a.z * b.y;
	g.y = a.z * b.x - a.x * b.z;
	g.z = a.x * b.y - a.y * b.x;
	if (! bezero(g.z))
	g.x /= g.z; g.y /= g.z; g.z = 1;
	return g;
}

         这是外带归一化的。

         两点叉积是直线,两线叉积是交点,至于点在线上,线过点,用点积就可以了。(how beautiful)




        知道了叉积总的用用吧;

        那就极角排序吧, 想了一堆办法来避免判象限,最终还是投降了(老老实实写象限吧)


int where(line a)
{
	if (a.x < -eps & a.y < eps) return 1;
	if (a.x > eps & a.y > -eps) return 3;
	if (a.x > -eps & a.y < -eps) return 2;
	return 4;
}

bool checks(line a, line b)
{
	int ka = where(a), kb = where(b);
	if (ka > kb) return false;
	if (ka < kb) return true;
	int k = cross2(lin[0], a, lin[0], b);
	if  (k > 0) return true;
	if  (k < 0) return false;
	if  (a.d - b.d < -eps ) return true;
	return false; 
}

void sort(int l , int r)
{
	int i = l, j = r;
	line tmp, g = lin[(l + r)>> 1];
	for (;i <= j;)
	{
		for (;checks(lin[i],g); i++);
		for (;checks(g,lin[j]); j--);
		if (i <= j)
		   tmp = lin[i], lin[i] = lin[j], lin[j] =tmp, i++, j--;
	}
	if (l < j) sort(l, j);
    if (i < r) sort(i, r);
}

          纯手工打造快排,不要bs;


          凸包是老早就写过了的水平序graham


void work()
{
	sort(1, n);
	top = 1; st[1] = 1;
 	for (i = 2; i <= n; i++)
	{
	    for (; top > 1 & cross(a[st[top-1]], a[i], a[st[top-1]], a[st[top]]) <= 0; top--);
	    st[++top] = i;
	}
	int k = top;
	for (i = n-1; i >= 1; i--)
	{
	    for (; top > k & cross(a[st[top-1]], a[i], a[st[top-1]], a[st[top]]) <= 0; top--);
	    st[++top] = i;
	}	
	top--;
}

           事先排过序的。总感觉很丑很丑........


           用凸包干啥nian, 旋转卡壳蛮不错的:

           (这个还是贴题目吧)

          最远点对:

# include <cstdio>
# include <cstdlib>
# include <cstring>

struct point 
{
	long long x, y;
};

const int maxn = 100000 + 5;

int i, n, top;
long long ans;
point a[maxn];
int st[maxn];


using namespace std;

inline long long max(long long a, long long b)
{
	return a > b? a : b;
}

inline long long cross(point a, point b, point c, point d)
{
	long long x1 = b.x - a.x, y1 = b.y - a.y;
	long long x2 = d.x - c.x, y2 = d.y - c.y;
	return x1 * y2 - x2 * y1;
}

inline long long sqr(long long a)
{
	return a * a;
}

inline long long dist(point a, point b)
{
	return (sqr(a.x - b.x) + sqr(a.y - b.y));
}

void sort(int l, int r)
{
	int i = l, j = r;
	point tmp, g = a[(l + r) >> 1];
	for (;i <= j;)
	{
		for (; a[i].y < g.y ||(a[i].y == g.y & a[i].x < g.x); i++);
		for (; a[j].y > g.y ||(a[j].y == g.y & a[j].x > g.x); j--);
		if (i <= j)
		  tmp = a[i], a[i] = a[j], a[j] = tmp, i++, j--;
	}
	if (i < r) sort(i, r);
	if (l < j) sort(l, j);
}

void prepare()
{
	sort(1, n);
	st[1] = 1; st[2] = 2; top = 2;
	int i; 
	for (i = 3; i <= n; i++)
	{
		for (;top > 1 & cross(a[st[top - 1]], a[i], a[st[top - 1]], a[st[top]]) <= 0; top --);
		st[++top] = i; 
	}
	int k = top;
	for (i = n - 1; i >= 1; i--)
	{
		for (;top > k & cross(a[st[top - 1]], a[i], a[st[top - 1]], a[st[top]]) <= 0; top --);
		st[++top] = i;
	}
	
}

void work()
{
	top --;
	int j = 2;
	for (i = 1; i <= top; i++)
	{
		for (;cross(a[st[i]], a[st[j]], a[st[i]], a[st[i + 1]]) < cross(a[st[i]], a[st[j + 1]], a[st[i]], a[st[i + 1]]);)
		   {j++; if (j > top) j = 1;}
		ans = max(ans, dist(a[st[i]], a[st[j]]));
	}
}

int main()
{
	freopen("2187.in", "r", stdin);
	freopen("2187.out", "w", stdout);
	scanf("%d", &n);
	int i;
	for (i = 1; i <= n; i++)
	  scanf("%I64d%I64d", &a[i].x , &a[i].y);
	prepare();
	if (top == 2)  { printf("%d", 0); return 0;}
	if (top == 3)  { printf("%I64d", dist(a[st[1]], a[st[2]])); return 0;}
	work();
	printf("%I64d", ans);
	return 0;
}


          

          最大三角形距离:

# include <cstdio>
# include <cstdlib>
# include <cstring>

struct point 
{
	int x, y;
};

const int maxn = 100000;
int ans, k, i, j, n, top;
point a[maxn];
int st[maxn];

int cross(point a, point b, point c, point d)
{
    int x1 = b.x - a.x, y1 = b.y - a.y;
    int x2 = d.x - c.x, y2 = d.y - c.y;
    return x1 * y2 - x2 * y1;
}

int max(int a, int b)
{
	return a > b? a: b;
}

void sort(int l, int r)
{
	int i = l, j = r;
	point tmp, g = a[(l + r) >> 1];
	for (;i <= j;)
	{
		for (;a[i].y < g.y || (a[i].y == g.y & a[i].x < g.x);i++);
		for (;a[j].y > g.y || (a[j].y == g.y & a[j].x > g.x);j--);
		if (i <= j)
		   tmp = a[i], a[i] = a[j], a[j] = tmp, i++, j--;
	}
	if (i < r) sort(i, r);
	if (l < j) sort(l, j);
}

void work()
{
	sort(1, n);
	top = 1; st[1] = 1;
 	for (i = 2; i <= n; i++)
	{
	    for (; top > 1 & cross(a[st[top-1]], a[i], a[st[top-1]], a[st[top]]) <= 0; top--);
	    st[++top] = i;
	}
	int k = top;
	for (i = n-1; i >= 1; i--)
	{
	    for (; top > k & cross(a[st[top-1]], a[i], a[st[top-1]], a[st[top]]) <= 0; top--);
	    st[++top] = i;
	}	
	top--;
}

void find_max()
{
	for (i = 1; i <= top; i++)
	{
	  k = i + 2; if (k > top) k -= top; 
	  for (j = i + 1; j <= top; j++)
	  {
			for (;abs(cross(a[st[i]], a[st[j]], a[st[i]], a[st[k+1]])) > abs(cross(a[st[i]], a[st[j]], a[st[i]], a[st[k]]));)
			{ k++; if (k > top) k -= top;}
			ans = max(ans, abs(cross(a[st[i]], a[st[j]], a[st[i]], a[st[k]])));	  
	  }
	}
	double p = ans/ 2.0;
	ans = 0; 
	printf("%.2lf\n", p);
}

int main()
{
	freopen("2079.in", "r", stdin);
	freopen("2079.out", "w", stdout);
    ans = 0;
	for (;;)
	{
	   scanf("%d", &n);
	   if (n == -1) return 0;
	   memset(a, 0, sizeof(a));
	   memset(st, 0, sizeof(st));
	   for (i = 1; i <= n; i++)
			scanf("%d%d", &a[i].x, &a[i].y);
       work();
       find_max();
    }
	return 0;
}

          旋转卡壳什么的,原来是没有直线的,只是用叉积判了一下方向而已,(how beautiful ,too)


          当然,对于凸包间的最短距离,是可以用Minkowski和做的(注意:  闵可夫斯基 貌似不是俄国人, 是德国人)

             Minkowski和 就是把两个凸包按同一方向的向量排序后,依次连接, 得到一个大凸包;

          容易理解,若对于凸包A,B:  A+B={(xiA+xjB,yiA+yjB):(xiA,yiA )∈A,(xjB,yjB)∈B} 的凸包就是Minkowski和在平移一下就行了;

          集训队那道题瞬间水了......

          area:

          

# include <cstdio>
# include <cstdlib>
# include <cstring>

using namespace std;

struct point
{
	long long x, y;
};

const int maxn = 500000;
int top, i, j, n, m, topa, topb;
point a[maxn], b[maxn], sd[maxn];
int sta[maxn], stb[maxn];

long long ans;

long long cross(point a, point b, point c, point d)
{
	long long x1 = b.x - a.x, y1 = b.y - a.y;
	long long x2 = d.x - c.x, y2 = d.y - c.y;
	return x1 * y2 - x2 * y1;
}

void sort(point *c, int l, int r)
{
	int i = l, j = r;
	point tmp,  g = c[l + rand() % (r - l + 1)];
	for (; i <= j;)
	{
		for (; c[i].y < g.y || (c[i].y == g.y & c[i].x < g.x); i++);
		for (; c[j].y > g.y || (c[j].y == g.y & c[j].x > g.x); j--);
		if (i <= j)
		   tmp = c[i], c[i] = c[j], c[j] = tmp, i++, j--;
	}
	if (i < r) sort (c, i, r);
	if (l < j) sort (c, l, j);
} 


void work(point *c, int n, int *stc, int &topc)
{
	topc = 1, stc[1] = 1;
	for (i = 2; i <= n; i++)
	{
		for (;topc > 1 & cross(c[stc[topc - 1]], c[i], c[stc[topc - 1]], c[stc[topc]]) <= 0;topc--);
	    stc[++topc] = i;
	}
	int k = topc;
	for (i = n - 1; i >= 1; i--)
	{
		for (;topc > k & cross(c[stc[topc - 1]], c[i], c[stc[topc - 1]], c[stc[topc]]) <= 0;topc--);
		stc[++topc] = i;
	}
}

int got(point a, point b)
{
	int x1 = b.x - a.x, y1 = b.y - a.y;
	if (x1 < 0 & y1 <= 0) return 1;
	if (x1 >= 0 & y1 < 0) return 2;
	if (x1 > 0 & y1 >= 0) return 3;
	/*if (x1 <= 0 & y1 > 0)*/ return 4;
}

bool checks (point a, point b, point c, point d)
{
	int k1 = got(a, b); int k2 = got(c, d);
	if (k1 < k2) return true;
	if (k1 > k2) return false;
	if (cross(a, b, c, d) > 0) return true;
	return false; 
}

void sort2(int l, int r)
{
    int i = l, j = r;
	point tmp,  g = sd[l + rand()% (r - l + 1)];
	for (; i <= j;)
	{
		for (; checks(sd[0], sd[i], sd[0], g) ; i++);
		for (; checks(sd[0], g, sd[0], sd[j]) ; j--);
		if (i <= j)
		   tmp = sd[i], sd[i] = sd[j], sd[j] = tmp, i++, j--;
	}
	if (i < r) sort2 (i, r);
	if (l < j) sort2 (l, j);	
}

int main()
{
	freopen("area.in", "r", stdin);
	freopen("area.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++)
	   scanf("%I64d%I64d", &a[i].x, &a[i].y);
	for (i = 1; i <= m; i++)
	   scanf("%I64d%I64d", &b[i].x, &b[i].y);
	sort (a, 1, n); 
	work(a, n, sta, topa);
	sort (b, 1, m); 
	work(b, m, stb, topb);
	top = 0;
	for (i = 1; i <= topa -1; i++)
	   sd[++top].x = a[sta[i + 1]].x - a[sta[i]].x, sd[top].y = a[sta[i + 1]].y - a[sta[i]].y;
	for (i = 1; i <= topb -1; i++)
	   sd[++top].x = b[stb[i + 1]].x - b[stb[i]].x, sd[top].y = b[stb[i + 1]].y - b[stb[i]].y;
    sd[0].x = 0; sd[0].y = 0;
	sort2(1, top);
    long long dx = 0, dy = 0, ex = 0, ey = 0;
    for (i = 1; i <= top; i++)
    {
		ex = dx + sd[i].x;
		ey = dy + sd[i].y;
		ans += dx * ey - ex * dy;
		dx = ex; dy = ey;
	}
	if (ans < 0) ans = -ans;
	printf("%I64d", ans);
	return 0;
}

                   令-B 就是B点集的每一个点的坐标都取反,那么Minkowski差就可以求凸包最近点:

                   求出A-B, 平移后,距离原点的距离就是凸包间最短距离了。





                   最后还剩半平面交;

                   zzy的s&l 还是挺容易写的,除了还不是很理解;

                  主要思路是用双端队列维护,按极角序插入,进队列前判断如果前两个或后两个半平面的交点在要插入的

            半平面外,就往里踢。

                   只是还有一些题目死活过不了+.+!

                   

                  判不等式组是否有解:poj1755

# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cmath>

using namespace std;

struct line
{
	double x, y, z, d;
};

struct point 
{
	double x, y, z;
};

int t;
const int maxn = 200;
line ll[maxn], lin[maxn], ask[maxn];
int n, tot, que[maxn];
const double eps = 1e-18, oo = 1073741819.1;
double low;

bool bezero(double x)
{
	return x > -eps & x < eps ? true: false;
}

double sqr(double x)
{
	return x*x;
}

int cross2(line a, line b, line c, line d)
{
	double x1 = b.x - a.x, y1 = b.y - a.y;
	double x2 = d.x - c.x, y2 = d.y - c.y;
	double k = x1 * y2 - x2 * y1;
	if (k > eps) return 1; 
	else if (k < -eps) return -1;
	else return 0; 
}

double abs(double x)
{
	return x < 0? -x : x;
}

point cross(line a, line b)
{
	point g;
	g.x = a.y * b.z - a.z * b.y;
	g.y = a.z * b.x - a.x * b.z;
	g.z = a.x * b.y - a.y * b.x;
	if (! bezero(g.z))
	 g.x /= g.z, g.y /=g.z, g.z = 1;
	return g;
}

int where(line a)
{
	if (a.x < -eps & a.y < eps) return 1;
	if (a.x > eps & a.y > -eps) return 3;
	if (a.x > -eps & a.y < -eps) return 2;
	return 4;
}

bool checks(line a, line b)
{
	int ka = where(a), kb = where(b);
	if (ka > kb) return false;
	if (ka < kb) return true;
	int k = cross2(lin[0], a, lin[0], b);
	if  (k > 0) return true;
	if  (k < 0) return false;
	if  (a.d - b.d < -eps ) return true;
	return false; 
}

void sort(int l , int r)
{
	int i = l, j = r;
	line tmp, g = lin[(l + r)>> 1];
	for (;i <= j;)
	{
		for (;checks(lin[i],g); i++);
		for (;checks(g,lin[j]); j--);
		if (i <= j)
		   tmp = lin[i], lin[i] = lin[j], lin[j] =tmp, i++, j--;
	}
	if (l < j) sort(l, j);
    if (i < r) sort(i, r);
}

bool stayin(line a, point b)
{
	if (bezero(b.z)) return false;
	if (b.x * a.x + b.y * a.y + a.z > eps) return true;
	return false;
}

bool check()
{
	lin[++tot].x = 0, lin[tot].y = 1, lin[tot].z = 0;
	lin[++tot].x = 1, lin[tot].y = 0, lin[tot].z = 0;
	lin[++tot].x = -1, lin[tot].y = 0, lin[tot].z = oo;
	lin[++tot].x = 0, lin[tot].y = -1, lin[tot].z = oo;
	sort (1, tot);
	int i, l = 1, r = 1;
	que[1] = 1;
	memset(ll, 0, sizeof(ll));
	t = 1;
	for (i = 2;i <= tot; i++)
	if (! bezero(lin[i].x * lin[i-1].y - lin[i-1].x * lin[i].y))
	{
		for (; (r - l) > 0 & (!stayin(lin[i], cross(lin[que[r]], lin[que[r-1]]))); r--);
		for (; (r - l) > 0 & (!stayin(lin[i], cross(lin[que[l]], lin[que[l+1]]))); l++);
		que[++r] = i;
	}
	for (; (r - l) > 0 & (!stayin(lin[que[l]], cross(lin[que[r]], lin[que[r-1]]))); r--);
	for (; (r - l) > 0 & (!stayin(lin[que[r]], cross(lin[que[l]], lin[que[l+1]]))); l++);
	if (r - l >= 2) return true;
	else return false;	
}

int main()
{
	int i, j;
	freopen("1755.in", "r", stdin);
	freopen("1755.out", "w", stdout);
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	   scanf("%lf%lf%lf", &ask[i].x, &ask[i].y, &ask[i].z);
	for (i = 1; i <= n; i++)
	{
		tot = 0;
		bool flag = false;
		memset(lin, 0, sizeof(lin));
		memset(que, 0, sizeof(que));
		for (j = 1; j <= n; j++)
		if (i != j)
		{
			if (ask[j].x-ask[i].x >-eps & ask[j].y-ask[i].y>-eps & ask[j].z -ask[i].z>-eps) flag = true;
			tot++;
			lin[tot].x = (ask[i].x - ask[j].x)/(ask[i].x*ask[j].x); //1 / ask[j].x - 1 / ask[i].x;
			lin[tot].y = (ask[i].y - ask[j].y)/(ask[i].y*ask[j].y);//1 / ask[j].y - 1 / ask[i].y;
			lin[tot].z = (ask[i].z - ask[j].z)/(ask[i].z*ask[j].z);//1 / ask[j].z - 1 / ask[i].z;
			low = sqrt(sqr(lin[tot].x) + sqr(lin[tot].y));
			lin[tot].d = lin[tot].z / low;
		}
		if (flag)  printf("No\n");
		else if (check()) printf("Yes\n");
		else  printf("No\n");
	}
	return 0;
}

                  多边形的核:poj3130

# include <cstdio>
# include <cstdlib>
# include <cmath>
# include <cstring>

using namespace std;

struct line
{
	double x, y, z;
};

struct point 
{
	double x, y, z;
};

const int maxn = 200;
const double eps = 1e-6;
line lin[maxn];
point a[maxn];
int que[maxn];
double tx = 0, ty = 0;
int l, r, n;

bool bezero(double x)
{
	return x < eps & x > -eps  ?true: false;
}

double sqr(double x)
{
	return x * x;
}

line getline(point a, point b)
{
	line g;
	g.x = a.y * b.z - a.z * b.y;
	g.y = a.z * b.x - a.x * b.z;
	g.z = a.x * b.y - a.y * b.x;
	double low = sqrt(sqr(g.x) + sqr(g.y));
	g.x /= low; g.y /= low; g.z /= low;
	return g;
}

point getpoint(line a, line b)
{
	point g;
	g.x = a.y * b.z - a.z * b.y;
	g.y = a.z * b.x - a.x * b.z;
	g.z = a.x * b.y - a.y * b.x;
	if (! bezero(g.z))
	g.x /= g.z; g.y /= g.z; g.z = 1;
	return g;
}

int cross2(line a, line b, line c, line d)
{
	double x1 = b.x - a.x, y1 = b.y - a.y;
	double x2 = d.x - c.x, y2 = d.y - c.y;
	double g = x1 * y2 - x2 * y1;
	if (g < -eps) return -1;
	if (g > eps) return 1;
	return 0;
}

int where(line a)
{
   if (a.x < -eps & a.y < eps) return 1;
   if (a.x > -eps & a.y < -eps) return 2;
   if (a.x > eps & a.y > -eps) return 3;
   return 4;
}

bool checks(line a, line b)
{
	int ka = where(a), kb = where(b);
	if (ka < kb) return true;
	if (ka > kb) return false;
	int g = cross2(lin[0], a, lin[0], b);
	if (g > 0) return true;
	if (g < 0) return false;
	if (a.z - b.z < -eps) return true;
	return false; 
}

void sort(int l, int r)
{
	int i = l, j = r;
	line tmp, g = lin[(l + r) >> 1];
	for (;i <= j;)
	{
		for (;checks(lin[i],g);i++);
		for (;checks(g,lin[j]);j--);
		if (i <= j)
		  tmp = lin[i], lin[i] = lin[j], lin[j] = tmp, i++, j--;
	}
	if (i < r) sort(i, r);
	if (l < j) sort(l, j);
}

void prepare()
{
	int i;
	memset(a, 0, sizeof(a));
	tx = 0; ty = 0;
	//scanf("%d", &n);
	for (i = n; i >= 1; i--)
	{
	   scanf("%lf%lf", &a[i].x, &a[i].y);
	   a[i].z = 1;
    }
    memset(lin, 0, sizeof(lin));
	a[n+1] = a[1];
	for (i = 1; i <= n; i++)
	   lin[i] = getline(a[i], a[i + 1]);
	for (i = 1; i <= n; i++)
	{
		point k; k.x = a[i+1].x - a[i].x; k.y = a[i+1].y - a[i].y; a[i].z = 1; 
	    if  (k.x * lin[i].y - k.y * lin[i].x > eps)
		lin[i].x = -lin[i].x, lin[i].y = -lin[i].y, lin[i].z = -lin[i].z;
    }
	sort(1, n);
}

bool stayin(line a, point b)
{
	return a.x * b.x + a.y * b.y + a.z < eps || bezero(b.z)? false: true;
}

void proce()
{
	int i;
	prepare();
	memset(que, 0, sizeof(que));
	l = 1; r = 1; que[1] = 1;
	for (i = 2; i <= n; i++)
	if (! bezero(lin[i].x * lin[i-1].y - lin[i-1].x * lin[i].y))
	{
		for (;r > l & (!stayin(lin[i], getpoint(lin[que[r]], lin[que[r-1]]))); r--);
		for (;r > l & (!stayin(lin[i], getpoint(lin[que[l]], lin[que[l+1]]))); l++);
		que[++r] = i;
	}
	for (;r > l & (!stayin(lin[que[l]], getpoint(lin[que[r]], lin[que[r-1]]))); r--);
	for (;r > l & (!stayin(lin[que[r]], getpoint(lin[que[l]], lin[que[l+1]]))); l++);
	if  (r - l >= 2) printf("1\n");
	else printf("0\n"); 		
}

int main()
{
	int t, i;
	freopen("3130.in", "r", stdin);
	freopen("3130.out", "w", stdout);
	for (;;)
	{
		scanf("%d", &n);
		if (n == 0) break;
	    proce();
    }
	return 0;
}


你可能感兴趣的:(【计算几何小结】)