题面
题意
平面上有n+1个洞,洞两两之间有一个球,第i个球到左边的洞的距离为((i*2-2)*x+d),第i个球到右边的洞的距离为(i*2-1)*x+d,每次随机选择一个不在洞中的球,再随机选择一个方向推动,球将会进入这个方向上距离它最近的没有球的洞(洞里如果有球将会跳过这个洞继续滚动)。
现在求所有球进洞后,球滚动的期望总距离。
做法
首先球到的洞的距离是一个等差数列:d,d+x,d+2x,d+3x,d+4x……….d+(2*n-1)x.
然后可以发现经过一次操作后上述序列变短而且仍然为等差数列,例如:
n=4,d=1,x=1时,
初始的序列为1,2,3,4,5,6,7,8
第一次操作后一共有八种可能:
1.第一个球向左滚:3 4 5 6 7 8
2.第一个球向右滚:6 4 5 6 7 8
3.第二个球向左滚:1 9 5 6 7 8
4.第二个球向右滚:1 2 12 6 7 8
5.第三个球向左滚:1 2 3 15 7 8
6.第三个球向右滚:1 2 3 4 18 8
7.第四个球向左滚:1 2 3 4 5 21
8.第四个球向右滚:1 2 3 4 5 6
上述8个序列每一位取平均值后的序列为
158,278,398,518,638,758
15
8
,
27
8
,
39
8
,
51
8
,
63
8
,
75
8
因此只要计算出每次序列中的d和x变化的规律,每次操作前答案加上该序列的平均值即可。
代码
#include<iostream>
#include<cstdio>
#define db double
using namespace std;
int n;
db x,d,ans;
int main()
{
int i,j;
cin>>n>>d>>x;
for(;n;n--)
{
ans+=(d*2.0+(db)(2*n-1)*x)/2.0;
d+=d/(db)n+5.0*x/(db)(2*n);
x+=2.0*x/(db)n;
}
printf("%.10f",ans);
}