链接
https://odzkskevi.qnssl.com/0675dd7b9a0ce4546b9c81729128719d?v=1537707195
题解
这是一个经典的几何概型,设两人到达的时间分别为
x
,
y
x,y
x,y,那么
∣
x
−
y
∣
<
w
|x-y|<w
∣x−y∣<w的时候,两人才能会面,对应到平面直角坐标系中,这个区域是
y
=
x
+
w
y=x+w
y=x+w和
y
=
x
−
w
y=x-w
y=x−w之间的开放区域
基本事件空间是以
(
s
1
,
t
1
)
,
(
s
1
,
t
2
)
,
(
s
2
,
t
1
)
,
(
s
2
,
t
2
)
(s_1,t_1),(s_1,t_2),(s_2,t_1),(s_2,t_2)
(s1,t1),(s1,t2),(s2,t1),(s2,t2)为四个顶点的矩形
这两个区域求一下交集,其面积与矩形作个比就是答案
求交集可以用半平面交
代码
#include <bits/stdc++.h>
#define maxn 100
#define eps 1e-8
#define dinf 1e100
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
int tot;
struct point
{
double x, y;
point(double x, double y):x(x),y(y){}
point(){}
}pt[maxn], _;
struct vec
{
point pt; double x, y, th;
vec(point pt, double x, double y):pt(pt),x(x),y(y){}
vec(){};
}seg[maxn], q[maxn];
point operator+(point pt, vec v){return point(pt.x+v.x,pt.y+v.y);}
vec operator-(point p1, point p2){return vec(p2,p1.x-p2.x,p1.y-p2.y);}
vec operator+(vec v1, vec v2){return vec(_,v1.x+v2.x,v1.y+v2.y);}
vec operator-(vec v1, vec v2){return vec(_,v1.x-v2.x,v1.y-v2.y);}
double operator*(vec v1, vec v2){return v1.x*v2.y-v2.x*v1.y;}
vec operator*(vec v, double t){return vec(_,v.x*t,v.y*t);}
bool in(point p, vec v){return (p-v.pt)*v<-eps;}
bool operator<(const vec &v1, const vec &v2)
{return fabs(v1.th-v2.th)<eps?in(v1.pt,v2):v1.th<v2.th;}
point inter(vec v1, vec v2)
{
vec u=v1.pt-v2.pt; double t=v2*u/(v1*v2);
return v1.pt+v1*t;
}
void hpi()
{
int l, r, i, x;
for(i=1;i<=tot;i++)seg[i].th=atan2(seg[i].y,seg[i].x);
sort(seg+1,seg+tot+1);
for(x=1,i=2;i<=tot;i++)if(fabs(seg[i].th-seg[i-1].th)>eps)seg[++x]=seg[i];tot=x;
for(q[l=r=1]=seg[1],i=2;i<=tot;i++)
{
while(l<r and !in(inter(q[r],q[r-1]),seg[i]))r--;
while(l<r and !in(inter(q[l],q[l+1]),seg[i]))l++;
q[++r]=seg[i];
}
while(l<r and !in(inter(q[r],q[r-1]),q[l]))r--;
while(l<r and !in(inter(q[l],q[l+1]),q[r]))l++;
pt[tot=1]=inter(q[r],q[l]);
for(i=l;i<r;i++)pt[++tot]=inter(q[i],q[i+1]);
}
void work()
{
int i, t1, t2, s1, s2, w;
double S=0;
tot=0;
scanf("%d%d%d%d%d",&s1,&s2,&t1,&t2,&w);
seg[++tot]=point(s2,t1)-point(s1,t1);
seg[++tot]=point(s2,t2)-point(s2,t1);
seg[++tot]=point(s1,t2)-point(s2,t2);
seg[++tot]=point(s1,t1)-point(s1,t2);
seg[++tot]=vec(point(w,0),1,1);
seg[++tot]=vec(point(0,w),-1,-1);
hpi();
for(i=2;i<=tot;i++)S+=(pt[i]-pt[1])*(pt[i-1]-pt[1]);
printf("%.10lf\n",fabs(S)/2/(s2-s1)/(t2-t1)+eps);
}
int main()
{
int T, kase;
scanf("%d",&T);
for(kase=1;kase<=T;kase++)
{
printf("Case #%d: ",kase);
work();
}
return 0;
}