UVA1388 Graveyard 公式由来详解

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

话不多说直接贴代码

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累加的由来,此文写给同样萌萌的你们。

  1. 设原周长CCC
  2. 加入mmm个点后周长为n+mn+mn+m
  3. n+mn+mn+m个点每点坐标为iii
  4. 原来n个点每点坐标为(n+m)/n∗i=(1+m/n)∗i(n+m)/n*i=(1+m/n)*i(n+m)/ni=(1+m/n)i
  5. 需要注意的是这里的3和4的iii不是一回事,3仅是说明加入mmm个点后每个点的坐标都在整数位置上,4的iii说明原来的n个点不一定在整数位置上,仅当m是n的整数倍时i[0,...,n−1]i[0,...,n-1]i[0,...,n1]点在整数位。

综上可知为了加入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

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值