题意: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;
}
分类: 文章

0 条评论

发表回复

Avatar placeholder

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