题意:A和B两位战友坐火车经停同一个车站,在[t1,t2]间的任意一个时刻,A的火车会停靠,在[s1,s2]间的任意一个时刻,B的火车会停靠,停靠事件都为w,求它们有时间并肩作战的概率。(s1,s2,t1,t2∈[90,1080],w属于[1,90])

思路:如果用二元组(x,y)表示AB分别在时刻x,y停靠,那么当且仅当|x-y|<=2w时,他们又机会见面。如果在平面上看二元组(x,y)则所有可能的(x,y)的集合是一个长方形S。而|x-y|<=2w是直线y=x+w和y=x-w所夹部分E。因此,我们要求落在E和S的交集部分的点占落在S内的点的比例。即面积比。

所以凭借小学几何知识我们就能经过分类讨论得出答案。只是分类讨论稍多。给出一个分类讨论思路:我们可以根据过每个有用的点的平行于y=x的直线的b值分类。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

int t,w;
double t1,t2,s1,s2;

double work()       //小学数学部分
{
    double b1,b2,b0,b3,bu,bd;       //分别为矩形四个点从大到小的b值,bu是w,bd是-w
    b1=s1-t1,b2=s2-t2,b0=s2-t1,b3=s1-t2;
    double a1,a2,a3;
    a1=(b0-b1)*(b0-b1)/2;
    a2=(s2-s1)*(b1-b2);
    a3=(b2-b3)*(b2-b3)/2;
    bu=w,bd=-w;
    double area1,area2;
    if(bd>=b0)area1=0;
    else if(bd<b0&&bd>=b1)area1=(b0-bd)*(b0-bd)/2;
    else if(bd<b1&&bd>=b2)area1=a1+(s2-s1)*(b1-bd);
    else if(bd<b2&&bd>=b3)area1=a1+a2+a3-(bd-b3)*(bd-b3)/2;
    else area1=a1+a2+a3;
    if(bu>=b0)area2=0;
    else if(bu<b0&&bu>=b1)area2=(b0-bu)*(b0-bu)/2;
    else if(bu<b1&&bu>=b2)area2=a1+(s2-s1)*(b1-bu);
    else if(bu<b2&&bu>=b3)area2=a1+a2+a3-(bu-b3)*(bu-b3)/2;
    else area2=a1+a2+a3;
    return (area1-area2)/(a1+a2+a3);
}

int main()
{
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    scanf("%d",&t);
    for(int q=1;q<=t;q++)
    {
        scanf("%lf%lf%lf%lf%d",&t1,&t2,&s1,&s2,&w);
        if(s1-t1<s2-t2)swap(s1,t1),swap(s2,t2);     //如果输入不适合计算,将矩形对称不改变答案。
        printf("Case #%d: %.8f\n",q,work());
    }
    return 0;
}
分类: 文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

你是机器人吗? =。= *