【計算幾何小結】

          貌似好久沒寫總結了,都快不會寫了。

          懶得分成幾篇了,就一起擠一擠吧。


          另外, 這裏有分開寫的

         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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章