zoukankan      html  css  js  c++  java
  • poj 1279 Art Gallery

    /*
    poj 1279 Art Gallery - 求多边形核的面积
    */
    #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);
    }
    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;
    }
    //求多边形面积
    double mo_area_polygon(point *dian,int n)
    {
    	int i;
    	point yuan;
    	yuan.x=yuan.y=0;
    	double ret=0;
    	for(i=0;i<n;++i)
    	{
    		ret+=mo_xmult(dian[(i+1)%n],yuan,dian[i]);
    	}
    	return ret;
    }
    
    int main()
    {
    	int i,iofcase=1,t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&n);
    		yong=0;
    		for(i=0;i<n;++i)
    		{
    			scanf("%lf%lf",&dian[i].x,&dian[i].y);
    		}
    		double area=mo_area_polygon(dian,n);
    		if(area<0)//若是顺时针
    		{
    			for(i=0;i<n;++i)
    			{
    				mo_HPI_addl(dian[(i+1)%n],dian[i]);
    			}
    		}else
    		{
    			for(i=0;i<n;++i)
    			{
    				mo_HPI_addl(dian[i],dian[(i+1)%n]);
    			}
    		}
    		int ret=mo_HalfPlaneIntersect(xian,n,jiao);
    		area=mo_area_polygon(jiao,ret);
    		if(area<0) area=-area;
    		area=area/2;
    		printf("%.2lf
    ",area);
    	}
    	return 0;
    }	


  • 相关阅读:
    How To Build CyanogenMod Android for smartphone
    CentOS安装Code::Blocks
    How to Dual boot Multiple ROMs on Your Android SmartPhone (Upto Five Roms)?
    Audacious——Linux音乐播放器
    How to Dual Boot Multiple ROMs on Your Android Phone
    Everything You Need to Know About Rooting Your Android Phone
    How to Flash a ROM to Your Android Phone
    什么是NANDroid,如何加载NANDroid备份?
    Have you considered compiled a batman-adv.ko for android?
    BATMAN—Better Approach To Mobile Adhoc Networking (B.A.T.M.A.N.)
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3249107.html
Copyright © 2011-2022 走看看