打篮球 ( pass ) 图论
【题目描述】
信息组的同学是比较喜欢打篮球的。
喜欢打篮球的同学很容易发现传球在篮球运动中是非常重要的,球传的好也就意味着球
打的顺。经常传球虽然不一定保证
100%
概率进球,但是总归是使球场气氛更加活跃了。
现在我们来看一场篮球比赛,肉蟹队vs宇宙大总统队。每支队伍都有N个(肉蟹)或(宇宙大总统),现在轮到肉蟹队进攻。比赛可以看成在一个无限大的二维平面上进行,每个球员都有一个坐标篮筐也有一个坐标(50,0)。肉蟹们进攻的方式就是先传球若干次,再投篮。
一旦投篮,这一轮进攻就立即结束。
由于有宇宙大总统们的防御,所以肉蟹们传球和投篮都是有成功率的。
传球和投篮的轨迹可以看成一条线段。
关于传球和投篮的成功率如下:
传球:
Cp*(1-(ls/150)^2)*dr/(dr+1)
投篮:
(Cs*dr/(dr+1))^ln(ls)
其中
Cp和Cs
是给定的常数,ls是球的运动轨迹的长度,dr是防御队员的干扰系数,
由于宇宙大总统非常有智慧,所以大总统们知道他们既可以干扰传球的,也可以干扰接球的,既可以盖帽,也可以干扰球(这里干扰球不算犯规),因此dr就等于所有宇宙大总统到球运动轨迹两端点距离的最小值。
肉蟹们知道直接与宇宙大总统对抗是没有胜算的,所以她们对球场施了一个神秘的魔法,使得场上的所有人都瞬间变肉,以至于无法移动。
现在球在第一个肉蟹手上,请你设计一个传球和投篮的方案。求肉蟹们在这一轮就进球的概率最大是多少。
【输入数据】
第一行三个数,分别表示
N,Cp,Cs
接下来N行,每行两个数,表示肉蟹们的坐标
接下来N行,每行两个数,表示宇宙大总统们的坐标
【输出数据】
一行,一个数,即最大的概率。
精确到小数点后6位。
【输入样例1】
3 1 1
50 50
35 60
70 15
75 5
72 25
45 17
【输出样例1】
0.806732
【输入样例2】
1 0.5 0.5
50 4
50 3
【输出样例2】
0.146342
【输入样例3】
5 0.999999 0.8
50 50
40 50
40 40
40 30
50 20
50 41
44 29
48
27
45 41
48 64
【输出样例3】0.294171
【数据约定】
30%:1≤N≤ 5100%:1≤N≤ 500≤坐标≤ 1000≤Cp,Cs≤ 1
这题其实可以用DP和最短路做,我选择的是最短路。
这题其实可以用DP和最短路做,我选择的是最短路。
我们只需预处理一些数据,然后就可以跑一遍spfa,然后在一一和篮筐判定选出答案就可以了。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #define ll long long #define il inline #define db double using namespace std; int n; db cp,cs; struct rou { db x,y; }r[145]; struct tong { db x,y; }t[145]; il db distance(db x1,db y1,db x2,db y2) { db r1=x2-x1,r2=y2-y1; return (db)sqrt(r1*r1+r2*r2); } db dist1[145][145]; db dist2[145][145]; db dist[145]; db lan[145]; db gan[145]; db minx=9999; bool vis[145]; il void spfa() { int t[145]; int head=0,tail=1; t[0]=1; dist[1]=1; while(head!=tail) { int h=t[head++]; vis[h]=0; for(int i=1;i<=n;i++) { db ls=dist1[h][i],dr=min(gan[h],gan[i]); if(dist[i]<dist[h]*(cp*(1-(ls/150)*(ls/150))*(dr/(dr+1)))) { dist[i]=dist[h]*(cp*(1-(ls/150)*(ls/150))*(dr/(dr+1))); if(!vis[i]) { vis[i]=1; t[tail++]=i; } } } } } int main() { freopen("pass.in","r",stdin); freopen("pass.out","w",stdout); cin>>n>>cp>>cs; for(int i=1;i<=n;i++) cin>>r[i].x>>r[i].y; for(int i=1;i<=n;i++) cin>>t[i].x>>t[i].y; for(int i=1;i<=n;i++) lan[i]=distance(r[i].x,r[i].y,50.0,0); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { dist1[i][j]=dist1[j][i]=distance(r[i].x,r[i].y,r[j].x,r[j].y); dist2[i][j]=distance(r[i].x,r[i].y,t[j].x,t[j].y); } for(int i=1;i<=n;i++) gan[i]=9999; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) gan[i]=min(gan[i],dist2[i][j]); for(int i=1;i<=n;i++) minx=min(minx,distance(t[i].x,t[i].y,50.0,0)); spfa(); db ans=0; for(int i=1;i<=n;i++) { db dr=min(minx,gan[i]); ans=max(ans,dist[i]*(pow((cs*dr/(dr+1)),(log(lan[i]))))); } printf("%f\n",ans); return 0; }
PEACE