UVALive

来源:互联网 发布:生死狙击手游刷枪 软件 编辑:程序博客网 时间:2024/06/05 20:23

题目链接:
https://cn.vjudge.net/contest/183985#problem/G
题意:
给出n条线段。询问每次射中线段条数的期望
分析:

数学期望(mean)(或 均值,亦简称期望)是试验中每次可能结果的 概率乘以其结果的总和。

ac code:

/*    因此,只需要计算每一条线段的两个端点与    原点连线形成的两条线段之间的夹角值 /360 即可    因为每一支箭 每次最多能射中的 也只有 1 / 360个单位.   计算夹角的时候需要注意,   某些线段的端点可能在第三和第四象限内部,   这就导致了用atan2(比atan更精确一些)   计算得出的弧度可能大于π,因此需要特殊处理一下,   经过分析可知,最后计算出来的夹角   结果一定在180°内,(极限情况是平行,但是达不到),   线段的两个端点同在一二或同在三四或二四的时候,   得出来的差值一定都是小于180的,只有一四象限的时候,   会导致计算出错,本来是锐角,可是最后减出来的是钝角    temp = fabs(atan2(y1,x1)-atan2(y2,x2));    我们来看这样一组例子,a1 = 30(线段在第一象限左端点与原点形成的夹角)    a2 = 330(线段在第四象限右端点与原点形成的夹角,本来应该是30,    由于atan2计算得出330)    这样最后temp = 300 ,正确结果是60,此时用360°减去temp,正好得到了想要的结果    是不是很神奇?那么为什么用360-temp正好纠正了之前的错误呢?    接下来我们来推导一下,a2 = 330,a1 = 30,我们要纠正的是a2    这里由于取绝对值使得a1-a2,    变成了a2-a1,我们要纠正a2计算导致的错误,    把a2 换成360 - a2;这样子360 - temp = 360 - (a2-a1) = 360-a2+a1,    正好用360直接减去temp也能得到我们想要的结果,这样避免了分类讨论.*/#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<vector>#include<queue>using namespace std;const int inf = 0x3f3f3f3f;const double eps  = 1e-6;const long long mod = 1e9+7;double pi = 3.1415926;int main(){    int t,n;    cin>>t;    while(t--)    {            int x1,y1,x2,y2;            cin>>n;            double ans = 0;            double temp;            while(n--)            {                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);                //atan2用于给定斜率计算三角函数的角度(弧度制)                temp = fabs(atan2(y1,x1)-atan2(y2,x2));                if(temp>pi)//进行错误纠正                    temp = 2*pi-temp;                ans+=temp;            }            ans = ans/2.0/pi;//这里其实是一种化简,因为期望是求和,            //正规的计算公式是 对每一条线段的夹角值求和,即∑ (temp/2/pi),            printf("%.5lf\n",ans);    }    return 0;}

附atan2用法详解:
[http://www.cnblogs.com/dutlei/archive/2013/01/14/2860332.html]