题意:n个人排成一列跑步,前后两人之间相隔 u 米,每个人正常速度均为 v 米/秒。
当某个配送员排在最后的时候,他需要以当时自己的最高速度往前跑,直到超过排头的人 u 米,然后降回到原始速度 v米/秒。每个人最初的最高速度为c[i] 米/秒,每轮衰减d[i]米/秒,也就是说,如果i是第j个跑的,那么他的速度就是c[i]-(j-1)*d[i] 米/秒。
n个人初始以随机的顺序排列,每种顺序的概率完全相等,跑完一轮(每个人都追到排头一次,序列恢复原样)的期望需要的时间是多少?
分析:n个人,相隔u米,正常速度v (m/s),最后一个人需要加速向前跑直至超过第一个人u米,初始时最高速度c[i],衰减d[i]。
根据时间速度可以列出一个公式:
S=n*u+t*v (n*u是最后一个人到第一个人之间的固定要跑的距离,t*v是在最后一个人跑的时候,中间n-1个人移动的距离)
同时,根据第i个人排在第j个位置时的速度衰减得到:
S=(c[i]-(j-1)*d[i])*t
由这两个公式可以求出 t=n*u/(c[i]-(j-1)*d[i]-v)
因为排列是随机的,要求跑一轮的期望,需要每个人都在每个位置时需要花费的时间,则最后的结果为
res=sum(u/(c[i]-(j-1)*d[i]-v))(i,j 属于[0,n]),因为重复了n次,求期望时需要对n取平均,所以约掉n。
代码:
package CodeM;
import java.util.Scanner;
public class PhysicalTraining_2017A {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
double v=sc.nextDouble();
double u=sc.nextDouble();
double[] c=new double[n];
double[] d=new double[n];
for (int i=0;i<n;i++){
c[i]=sc.nextDouble();
}
for (int i=0;i<n;i++){
d[i]=sc.nextDouble();
}
double res=0;
for (int j=0;j<n;j++){
for (int i=0;i<n;i++){
res+=u/(c[i]-j*d[i]-v);
}
}
System.out.println(String.format("%.3f",res));
}
}
总结:A题和D题都使我在写代码之前,更乐于分析题目中提到的公式,因为这使得我的代码更加简洁。