poj 3130 How I Mathematician Wonder What You Are! - 求多边形有没有核 - 模版

 

/*

poj 3130 How I Mathematician Wonder What You Are! - 求多边形有没有核







*/

#include <stdio.h>

#include<math.h>

const double eps=1e-8;

const int N=103;

struct point

{

    double x,y;

}dian[N];

inline bool mo_ee(double x,double y)

{

	double ret=x-y;

	if(ret<0) ret=-ret;

	if(ret<eps) return 1;

	return 0;

}

inline bool mo_gg(double x,double y)  {   return x > y + eps;} // x > y

inline bool mo_ll(double x,double y)  {   return x < y - eps;} // x < y

inline bool mo_ge(double x,double y) {   return x > y - eps;} // x >= y

inline bool mo_le(double x,double y) {   return x < y + eps;} 	// x <= y

inline double mo_xmult(point p2,point p0,point p1)//p1在p2左返回负,在右边返回正

{

    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);

}



point mo_intersection(point u1,point u2,point v1,point v2)

{

    point ret=u1;

    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))

		/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));

    ret.x+=(u2.x-u1.x)*t;

    ret.y+=(u2.y-u1.y)*t;

    return ret;

}

/////////////////////////



//切割法求半平面交

point mo_banjiao_jiao[N*2];

point mo_banjiao_jiao_temp[N*2];

void mo_banjiao_cut(point *ans,point qian,point hou,int &nofdian)

{

	int i,k;

	for(i=k=0;i<nofdian;++i)

	{

		double a,b;

		a=mo_xmult(hou,ans[i],qian);

		b=mo_xmult(hou,ans[(i+1)%nofdian],qian);

		if(mo_ge(a,0))//顺时针就是<=0

		{

			mo_banjiao_jiao_temp[k++]=ans[i];

		}if(mo_ll(a*b,0))

		{

			mo_banjiao_jiao_temp[k++]=mo_intersection(qian,hou,ans[i],ans[(i+1)%nofdian]);

		}

	}

	for(i=0;i<k;++i)

	{

		ans[i]=mo_banjiao_jiao_temp[i];

	}

	nofdian=k;

}

int mo_banjiao(point *dian,int n)

{

	int i,nofdian;

	nofdian=n;

	for(i=0;i<n;++i)

	{

		mo_banjiao_jiao[i]=dian[i];

	}

	for(i=0;i<n;++i)//i从0开始

	{

		mo_banjiao_cut(mo_banjiao_jiao,dian[i],dian[(i+1)%n],nofdian);

		if(nofdian==0)

		{

			return nofdian;

		}

	}

	return nofdian;

}

/////////////////////////

int main()

{

    int t,i,n;

    while(scanf("%d",&n),n)

    {

        

        for(i=0;i<n;++i)

        {

            scanf("%lf%lf",&dian[i].x,&dian[i].y);

        }

        int ret=mo_banjiao(dian,n);

        if(ret==0)

        {

            printf("0\n");

        }else

        {

            printf("1\n");

        }

    }

    return 0;

}


 


 

/*

为什么ret<3?

*/

#include<stdio.h>

#include<math.h>

#include <algorithm>  

using namespace std;  



const double eps=1e-8;

struct point 

{

	double x,y;

}dian[20000+10];

point jiao[203];

struct line  

{  

    point s,e;  

    double angle;  

}xian[20000+10];  

int n,yong;

bool mo_ee(double x,double y)  

{  

    double ret=x-y;  

    if(ret<0) ret=-ret;  

    if(ret<eps) return 1;  

    return 0;  

}  

bool mo_gg(double x,double y)  {   return x > y + eps;} // x > y     

bool mo_ll(double x,double y)  {   return x < y - eps;} // x < y     

bool mo_ge(double x,double y) {   return x > y - eps;} // x >= y     

bool mo_le(double x,double y) {   return x < y + eps;}     // x <= y     

point mo_intersection(point u1,point u2,point v1,point v2)  

{  

    point ret=u1;  

    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))  

		/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));  

    ret.x+=(u2.x-u1.x)*t;  

    ret.y+=(u2.y-u1.y)*t;  

    return ret;  

}  

double mo_xmult(point p2,point p0,point p1)//p1在p2左返回负,在右边返回正  

{  

    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);  

}  





void mo_HPI_addl(point a,point b)  

{  

	xian[yong].s=a;  

	xian[yong].e=b;  

	xian[yong].angle=atan2(b.y-a.y,b.x-a.x);  

	yong++;  

}  

//半平面交

bool mo_HPI_cmp(const line& a,const line& b)

{

	if(mo_ee(a.angle,b.angle))

	{

		return mo_gg( mo_xmult(b.e,a.s,b.s),0);

	}else

	{

		return mo_ll(a.angle,b.angle);

	}

}

int mo_HPI_dq[20000+10];

bool mo_HPI_isout(line cur,line top,line top_1)

{

	point jiao=mo_intersection(top.s,top.e,top_1.s,top_1.e);

	return mo_ll( mo_xmult(cur.e,jiao,cur.s),0);//若顺时针时应为mo_gg

}

int mo_HalfPlaneIntersect(line *xian,int n,point *jiao)

{

	int i,j,ret=0;

	sort(xian,xian+n,mo_HPI_cmp);

	for (i = 0, j = 0; i < n; i++)

	{

		if (mo_gg(xian[i].angle,xian[j].angle))

		{

			xian[++j] = xian[i];

		}

	}

	n=j+1;

	mo_HPI_dq[0]=0;

	mo_HPI_dq[1]=1;

	int top=1,bot=0;

	for (i = 2; i < n; i++)

	{

        while (top > bot && mo_HPI_isout(xian[i], xian[mo_HPI_dq[top]], xian[mo_HPI_dq[top-1]])) top--;

        while (top > bot && mo_HPI_isout(xian[i], xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[bot+1]])) bot++;

        mo_HPI_dq[++top] = i; //当前半平面入栈

	}

    while (top > bot && mo_HPI_isout(xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[top]], xian[mo_HPI_dq[top-1]])) top--;

    while (top > bot && mo_HPI_isout(xian[mo_HPI_dq[top]], xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[bot+1]])) bot++;

    mo_HPI_dq[++top] = mo_HPI_dq[bot];

    for (ret = 0, i = bot; i < top; i++, ret++)

	{

		jiao[ret]=mo_intersection(xian[mo_HPI_dq[i+1]].s,xian[mo_HPI_dq[i+1]].e,xian[mo_HPI_dq[i]].s,xian[mo_HPI_dq[i]].e);

	}

	return ret;

}

int main()

{

	int i;

	while(scanf("%d",&n),n)

	{

		yong=0;

		for(i=0;i<n;++i)

		{

			scanf("%lf%lf",&dian[i].x,&dian[i].y);

		}

		for(i=0;i<n;++i)

		{

			mo_HPI_addl(dian[i],dian[(i+1)%n]);

		}

		int ret=mo_HalfPlaneIntersect(xian,n,jiao);

		if(ret<3)

		{

			printf("0\n");

		}else

		{

			printf("1\n");

		}

	}

	return 0;

}	


 

 

你可能感兴趣的:(Math)