转自:http://www.cnblogs.com/mypsq/p/4366893.html
HDU - 2892
Description 小白最近被空军特招为飞行员,参与一项实战演习。演习的内容是轰炸某个岛屿。。。 Input 首先输入三个数代表小白投弹的坐标(x,y,h); Output 输出一个两位小数,表示实际轰炸到的岛屿的面积。 |
模板:
#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\n",fabs(sum));
}
return 0;
}