zoukankan      html  css  js  c++  java
  • 多边形和圆的相交面积(模板)hdu2892、hdu4404

    area

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 686    Accepted Submission(s): 265

    Problem Description
    小白最近被空军特招为飞行员,参与一项实战演习。演习的内容是轰炸某个岛屿。。。
    作为一名优秀的飞行员,任务是必须要完成的,当然,凭借小白出色的操作,顺利地将炸弹投到了岛上某个位置,可是长官更关心的是,小白投掷的炸弹到底摧毁了岛上多大的区域?
    岛是一个不规则的多边形,而炸弹的爆炸半径为R。
    小白只知道自己在(x,y,h)的空间坐标处以(x1,y1,0)的速度水平飞行时投下的炸弹,请你计算出小白所摧毁的岛屿的面积有多大. 重力加速度G = 10.
     
    Input
    首先输入三个数代表小白投弹的坐标(x,y,h);
    然后输入两个数代表飞机当前的速度(x1, y1);
    接着输入炸弹的爆炸半径R;
    再输入一个数n,代表岛屿由n个点组成;
    最后输入n行,每行输入一个(x',y')坐标,代表岛屿的顶点(按顺势针或者逆时针给出)。(3<= n < 100000)
     
    Output
    输出一个两位小数,表示实际轰炸到的岛屿的面积。
     
    Sample Input
    0 0 2000 100 0 100 4 1900 100 2000 100 2000 -100 1900 -100
     
    Sample Output
    15707.96
    #include"cstdio"
    #include"cstring"
    #include"cstdlib"
    #include"cmath"
    #include"string"
    #include"map"
    #include"cstring"
    #include"algorithm"
    #include"iostream"
    #include"set"
    #include"queue"
    #include"stack"
    #define inf 1000000000000
    #define M 100009
    #define LL long long
    #define eps 1e-12
    #define mod 1000000007
    #define PI acos(-1.0)
    using namespace std;
    struct node
    {
        double x,y;
        node(){}
        node(double xx,double yy)
        {
            x=xx;
            y=yy;
        }
        node operator -(node s)
        {
            return node(x-s.x,y-s.y);
        }
        node operator +(node s)
        {
            return node(x+s.x,y+s.y);
        }
        double operator *(node s)
        {
            return x*s.x+y*s.y;
        }
        double operator ^(node s)
        {
            return x*s.y-y*s.x;
        }
    }p[M];
    double max(double a,double b)
    {
        return a>b?a:b;
    }
    double min(double a,double b)
    {
        return a<b?a:b;
    }
    double len(node a)
    {
        return sqrt(a*a);
    }
    double dis(node a,node b)//两点之间的距离
    {
        return len(b-a);
    }
    double cross(node a,node b,node c)//叉乘
    {
        return (b-a)^(c-a);
    }
    double dot(node a,node b,node c)//点成
    {
        return (b-a)*(c-a);
    }
    int judge(node a,node b,node c)//判断c是否在ab线段上(前提是c在直线ab上)
    {
        if(c.x>=min(a.x,b.x)
           &&c.x<=max(a.x,b.x)
           &&c.y>=min(a.y,b.y)
           &&c.y<=max(a.y,b.y))
            return 1;
        return 0;
    }
    double area(node b,node c,double r)
    {
        node a(0.0,0.0);
        if(dis(b,c)<eps)
            return 0.0;
        double h=fabs(cross(a,b,c))/dis(b,c);
        if(dis(a,b)>r-eps&&dis(a,c)>r-eps)//两个端点都在圆的外面则分为两种情况
        {
            double angle=acos(dot(a,b,c)/dis(a,b)/dis(a,c));
            if(h>r-eps)
            {
                return 0.5*r*r*angle;
            }
            else if(dot(b,a,c)>0&&dot(c,a,b)>0)
            {
                double angle1=2*acos(h/r);
                return 0.5*r*r*fabs(angle-angle1)+0.5*r*r*sin(angle1);
            }
            else
            {
                return 0.5*r*r*angle;
            }
        }
        else if(dis(a,b)<r+eps&&dis(a,c)<r+eps)//两个端点都在圆内的情况
        {
            return 0.5*fabs(cross(a,b,c));
        }
        else//一个端点在圆上一个端点在圆内的情况
        {
            if(dis(a,b)>dis(a,c))//默认b在圆内
            {
                swap(b,c);
            }
            if(fabs(dis(a,b))<eps)//ab距离为0直接返回0
            {
                return 0.0;
            }
            if(dot(b,a,c)<eps)
            {
                double angle1=acos(h/dis(a,b));
                double angle2=acos(h/r)-angle1;
                double angle3=acos(h/dis(a,c))-acos(h/r);
                return 0.5*dis(a,b)*r*sin(angle2)+0.5*r*r*angle3;
    
            }
            else
            {
                double angle1=acos(h/dis(a,b));
                double angle2=acos(h/r);
                double angle3=acos(h/dis(a,c))-angle2;
                return 0.5*r*dis(a,b)*sin(angle1+angle2)+0.5*r*r*angle3;
            }
        }
    }
    int main()
    {
        double x,y,h,x1,y1,R;
        while(scanf("%lf%lf%lf",&x,&y,&h)!=-1)
        {
            scanf("%lf%lf%lf",&x1,&y1,&R);
            int n;
            scanf("%d",&n);
            for(int i=0;i<n;i++)
            {
                scanf("%lf%lf",&p[i].x,&p[i].y);
            }
            p[n]=p[0];
            double V=sqrt(2*10*h);
            double t0=V/10;
            double x0=x+x1*t0;
            double y0=y+y1*t0;
            node O(x0,y0);
            for(int i=0;i<=n;i++)
                p[i]=p[i]-O;
            O=node(0,0);
            double sum=0;
            for(int i=0;i<n;i++)
            {
                int j=i+1;
                double s=area(p[i],p[j],R);
                if(cross(O,p[i],p[j])>0)
                    sum+=s;
                else
                    sum-=s;
            }
            printf("%.2lf
    ",fabs(sum));
        }
        return 0;
    }
    

      

  • 相关阅读:
    全排列算法(java实现) 组合算法实现
    int -2147483648 ----- 2147483647
    Gradel 多渠道打包 代码混淆
    Android开发环境搭建
    自定义相册、九宫格显示图片
    新技术:retrofit
    新技术:dagger
    主流架构:MVVP
    GreenDao3.2的使用
    第三方框架:EventBus
  • 原文地址:https://www.cnblogs.com/mypsq/p/4366893.html
Copyright © 2011-2022 走看看