Uva3708 (一点处理技巧)

来源:互联网 发布:数据管控流程 编辑:程序博客网 时间:2024/06/06 08:57

solution

n个点等距放在周长为10000的圆上,现在要放多m个点,求每个点移动的最少距离和.

  • 一个结论,一定有一个点是不动的

  • 证明:废话

  • 那么,只要确定了一个点,剩下的点都确定了.

  • 直接判断其离得最近的点的距离即可.

  • 我要讲的是这里处理的技巧,这里处理很巧.

  • 首先把周长为10000的圆看作周长为n+m的圆.

  • 那么,我可以求出来原来n个点的对应位置,现在,我只要找到距离它最近的整数点即可.

  • 看如下代码:

#include <cstdio>#include <cmath>using namespace std;int main(){    int n,m;    while (scanf("%d%d",&n,&m) == 2)    {        double ans = 0.0;        for (int i = 1; i < n; i++){            double pos = (double) i / n * (n + m); //pos表示在n+m的线段上原来第i个点所对应的位置.            ans += fabs(pos - floor(pos + 0.5)); //这里能保证不会去到同一个整数点,原因是floor表示取整,而原来两两点之间的距离一定大于1,如果加0.5后取整相同则表示两个数的差一定小于1,矛盾.        }        printf("%.4lf\n",ans / (n + m) *10000);         }}
原创粉丝点击