zoukankan      html  css  js  c++  java
  • SHOI2012 信用卡凸包

    题意:

    题目链接
    题目大意:
    给出n个四角为pi/4的圆弧的类矩形,求它们凸包的周长

    思路:

    乍看似乎没有思路,但注意到r=0时求的是一个裸的凸包
    考虑当r不等于0时,我们先按之前的方法求出凸包周长
    然后对于每个拐点求其角度,而后求出这段圆弧长,累加即可。。。

    for(int i=1;i<=m;++i)
    {
    	ans+=(q[i]-q[i+1]).dist();
    	double cs=((q[i]-q[i+1])*(q[i+2]-q[i+1]))/(q[i]-q[i+1]).dist()/(q[i+1]-q[i+2]).dist();
            //点乘a*b=|a||b|cos<a,b>(a,b为向量)
    	double dg=pi-acos(cs);
    	ans+=dg*r;
    }
    
    

    最后提交AC后看了遍题解,发现圆弧累加后的总长度就是一个整圆的周长,直接加就可以了。

    for(int i=1;i<=m;++i)
    	ans+=(q[i]-q[i+1]).dist();
    ans+=2*pi*r;
    

    注意事项:

    pi指180度,而不是360度(这种错只有我才犯吧。。。)

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e4+5;
    const double eps=1e-7;
    const double pi=3.1415926535898;
    int n,m,cnt,per[N<<2];
    double a,b,r;
    struct point{double x,y;double dist(){return sqrt(x*x+y*y);}}p[N<<2],q[N<<2];
    point operator+(point x,point y){return (point){x.x+y.x,x.y+y.y};}
    point operator-(point x,point y){return (point){x.x-y.x,x.y-y.y};}
    double operator*(point x,point y){return x.x*y.x+x.y*y.y;}
    double operator^(point x,point y){return x.x*y.y-x.y*y.x;}
    inline double readin(){double x;scanf("%lf",&x);return x;}
    inline double lfabs(double x){return x<-eps?-x:x;}
    inline point rot(point pp,double dg)
    {
    	return (point){pp.x*cos(dg)-pp.y*sin(dg),pp.y*cos(dg)+pp.x*sin(dg)};
    }
    struct cmpfunctor{
    	inline bool operator()(int x,int y)
    	{
    		double dit=(p[x]-p[1])^(p[y]-p[1]);
    		if(lfabs(dit)>eps) return dit>eps;
    		return (p[x]-p[1]).dist()<(p[y]-p[1]).dist();
    	}
    };
    inline void Graham()
    {
    	for(int i=2;i<=cnt;++i)
    		if(p[i].x-p[1].x<-eps||(lfabs(p[i].x-p[1].x)<eps&&p[i].y-p[1].y<-eps))
    			swap(p[1],p[i]);
    	for(int i=1;i<=cnt;++i)per[i]=i;
    	sort(per+2,per+cnt+1,cmpfunctor());
    	q[++m]=p[1];
    	for(int i=2;i<=cnt;++i)
    	{
    		int j=per[i];
    		while(m>1&&((p[j]-q[m-1])^(q[m]-q[m-1]))>-eps) --m;
    		q[++m]=p[j];
    	}
    	q[m+1]=q[1];q[m+2]=q[2];
    }
    inline double C()
    {
    	double ans=0;
    	for(int i=1;i<=m;++i)
    		ans+=(q[i]-q[i+1]).dist();
    	return ans+2.0*pi*r;
    }
    int main()
    {
    	scanf("%d",&n);
    	scanf("%lf%lf%lf",&a,&b,&r);
    	for(int i=1;i<=n;++i)
    	{
    		point pt;scanf("%lf%lf",&pt.x,&pt.y);
    		point ne=(point){pt.x+b/2.0-r,pt.y+a/2.0-r};
    		point nw=(point){pt.x-b/2.0+r,pt.y+a/2.0-r};
    		double dg=readin();
    		p[++cnt]=rot(ne-pt,dg)+pt;p[++cnt]=rot(nw-pt,dg)+pt;
    		point ps=pt+pt-p[cnt];p[++cnt]=ps;
    		ps=pt+pt-p[cnt-2];p[++cnt]=ps;
    	}
    	Graham();
    	printf("%.2lf",C());
    	return 0;
    }
    
  • 相关阅读:
    AlexNet模型
    AlexNet详细解读
    Network in Network学习笔记
    在AlexNet中LRN 局部响应归一化的理
    深度学习相关转载收集
    网络结构解读之inception系列五:Inception V4
    网络结构解读之inception系列四:Inception V3
    网络结构解读之inception系列三:BN-Inception(Inception V2)
    网络结构解读之inception系列二:GoogLeNet(Inception V1)
    mac下安装启动Mongodb
  • 原文地址:https://www.cnblogs.com/zmyzmy/p/12231716.html
Copyright © 2011-2022 走看看