• 「SCOI2015」小凸想跑步 解题报告


    「SCOI2015」小凸想跑步

    最开始以为和多边形的重心有关,后来发现多边形的重心没啥好玩的性质

    实际上你把面积小于的不等式列出来,发现是一次的,那么就可以半平面交了


    Code:

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define Vector Point
    const int N=2e5+10;
    const double eps=1e-7;
    int n,m,l,r;
    struct Point
    {
    	double x,y;
    	Point(){}
    	Point(double X,double Y){x=X,y=Y;}
    	double angle(){return atan2(y,x);}
    	Vector friend operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
    	Vector friend operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
    	Vector friend operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
    }bee[N],q1[N];
    struct Line
    {
    	Point s,t;double ang;
    	Line(){}
    	Line(Point S,Point T){s=S,t=T,ang=(t-s).angle();}
    }yuu[N],q2[N];
    double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    bool isrig(Line a,Point b){return Cross(b-a.s,a.t-a.s)>0;}
    bool cmp(Line a,Line b){return fabs(a.ang-b.ang)<eps?isrig(a,b.t):a.ang<b.ang;}
    Point jd(Line a,Line b){return a.s+(a.t-a.s)*(Cross(a.s-b.s,b.t-b.s)/Cross(b.t-b.s,a.t-a.s));}
    void SI()
    {
    	std::sort(yuu+1,yuu+1+m,cmp);
    	q2[l=r=1]=yuu[1];
    	for(int i=2;i<=m;i++)
    		if(fabs(yuu[i].ang-yuu[i-1].ang)>eps)
    		{
    			while(l<r&&isrig(yuu[i],q1[r-1])) --r;
    			while(l<=r&&isrig(yuu[i],q1[l])) ++l;
    			q1[r]=jd(q2[r],yuu[i]);
    			q2[++r]=yuu[i];
    		}
    	while(l<r&&isrig(q2[l],q1[r-1])) --r;
    	q1[r]=jd(q2[l],q2[r]);
    }
    double area()
    {
        if(r-l<2) return 0;
    	double ret=0;
    	for(int i=l;i<r;i++) ret+=Cross(q1[i],q1[i+1]);
    	ret+=Cross(q1[r],q1[l]);
    	return ret/2;
    }
    int main()
    {
    	scanf("%d",&n);m=n;double sum=0;
    	for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&bee[i].x,&bee[i].y);
            yuu[i]=Line(bee[i-1],bee[i]);
            if(i!=1) sum+=Cross(bee[i-1],bee[i]);
        }
    	yuu[1]=Line(bee[n],bee[1]);
    	sum+=Cross(bee[n],bee[1]);
    	sum/=2;
    	bee[++n]=bee[1];
    	for(int i=3;i<=n;i++)
    	{
    		double A=bee[1].y-bee[2].y-(bee[i-1].y-bee[i].y);
    		double B=bee[2].x-bee[1].x-(bee[i].x-bee[i-1].x);
    		double C=Cross(bee[1],bee[2])-Cross(bee[i-1],bee[i]);
    		if(fabs(A)<eps) yuu[++m]=Line(Point(0,-C/B),Point(0,-C/B)+Vector(-B,A));
    		else yuu[++m]=Line(Point(-C/A,0),Point(-C/A,0)+Vector(-B,A));
    	}
    	SI();
    	printf("%.4f
    ",area()/sum);
    	return 0;
    }
    

    2019.3.4

  • 相关阅读:
    使用SO_REVTIMEO套接字选项为recvfrom设置超时
    使用select为描述符设置超时
    套接字超时设置方法
    使用SIGALARM为recvfrom设置超时
    使用SIGALARM为connect设置超时
    20200410 阿里巴巴Java开发手册
    20200409 Vue 视频学习【归档】
    20200319 Spring MVC 官方文档【归档】
    20200319 Spring Web MVC 2-5
    20200319 Spring Web MVC 1
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10469159.html
Copyright © 2020-2023  润新知