话不多说直接贴代码
void solve(){
int n, m;
while(cin >> n >> m){
double re = 0;
uu(i, 1, n){
double pos = (double)i / n * (n+m);
re += fabs(pos - floor(pos + 0.5)) / (n+m);
}
cout << re*1e4 << endl;
}
}
lrj书已经给出了一定深度的解释,但采集如我仍无法理解pos、re累加的由来,此文写给同样萌萌的你们。
- 设原周长CCC
- 加入mmm个点后周长为n+mn+mn+m
- n+mn+mn+m个点每点坐标为iii
- 原来n个点每点坐标为(n+m)/n∗i=(1+m/n)∗i(n+m)/n*i=(1+m/n)*i(n+m)/n∗i=(1+m/n)∗i
- 需要注意的是这里的3和4的iii不是一回事,3仅是说明加入mmm个点后每个点的坐标都在整数位置上,4的iii说明原来的n个点不一定在整数位置上,仅当m是n的整数倍时i[0,...,n−1]i[0,...,n-1]i[0,...,n−1]点在整数位。
综上可知为了加入mmm个点后原来的nnn个点需要各自跑到最近的整数位置上,这就是floor(pos+0.5)的由来,那么为什么后面会有/(n+m)/(n+m)/(n+m)呢,别急下面👇解释:
我们知道现在的点坐标是由CCC缩放到n+mn+mn+m的,那么回到原来的坐标就需要i/(n+m)∗Ci/(n+m)*Ci/(n+m)∗C,这里的iii是加入mmm个点后的整数坐标,CCC是公因式可以提出来放在最后乘,因此每一步计算累加的时候只看见了.../(n+m).../(n+m).../(n+m)而不见CCC。(题中C=1e4C=1e4C=1e4)

本文解析了一个涉及点坐标调整的算法,通过将原有坐标按比例映射到新增点后的坐标系中,并采用floor(pos+0.5)的方式使点尽可能靠近整数位置,以此来最小化坐标调整带来的误差。
1463





