题意: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 条评论