Problem: Graveyard
Description: 有
N
个墓地,均匀排布到一个周长为10000的圆周上。现在要加
Solution: 这个问题我看到的第一感觉就是枚举。我们要计算出
Code(C++):
#include <stdio.h>
#include <math.h>
const double L=10000;
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
double sig_pre=L/n;
double sig_now=L/(n+m);
double ans=0;
for(int i=1;i<n;i++){
double pos=sig_pre*i;
double pre_pos=sig_now*(int)(pos/sig_now);
double pre_pos2=pre_pos+sig_now;
ans+=pos-pre_pos>pre_pos2-pos? pre_pos2-pos:pos-pre_pos;
}
printf("%.4f\n",ans);
}
return 0;
}
而刘汝佳大神的解法和我的很相似,但是他代码和想法真的是精辟。他是把这个周长缩小的10000倍。然后利用四舍五入的方式去选择到哪个点。而且他还提到了会不会两个点同时移动到同一个点去。答案是肯定不会的。我们可以这么考虑。设N个墓地时的位置为 POS1 , N+M 个墓地时的位置为 POS2 。那么我们枚举 POS1时 会不会 POS11 和 POS12 都移动到 POS22 。这个自己画个图就很清楚了。 POS11 只有距离 POS22 的距离少于 DPOS21−POS22/2 的时候才会移动到 POS22 ,那么这个时候 POS12 距离 POS22 的距离就会大于 DPOS21−POS22/2 ,因为 DPOS11−POS12 大于 DPOS21−POS22 。这个时候 POS12 只能移动到 POS23 了。
Code(C++):
#include <stdio.h>
#include <math.h>
const double L=10000;
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
double ans=0;
for(double i=1;i<n;i+=1){
double pos=i/n*(n+m);
ans+=fabs(pos-(int)(pos+0.5))/(n+m);
}
printf("%.4f\n",ans*L);
}
return 0;
}