• LA 3708 Graveyard


    题目链接:

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1709

    题意:

    一个周长为10000的圆上等距离分布n个点,新增加m个点, 若使所有m+n个点等距离的分布在圆上,求原来n个点的最小移动距离。

    分析:

    看下样例,很容易想到是固定一个点不动,移动剩下n1个点,就是说以这个不动点为原点,顺时针放剩下的n+m1个点。
    起初想啊,算出每个点的距离之后,把这n1个点跟他相邻的点都比较一下找个最近的点,后来看了白书的做法, zz选手表示还是觉得很巧妙的。。
    他的思想是将这个圆分成n+m份,这样最后的n+m个点就分别占据着圆上的整数点,我们可以求出原始n个点的新坐标,这样距离他最近的整数点就是floor(x+0.5),把差累加即可。
    但是这样会不会出现两个原始点对应同一个整数点呢?只有当两个数的差小于1的时候他们的floor(x+0.5)才有可能相等,但是由于我们把n个点均等的放在了n+m的坐标系中,所以任何两个点的距离肯定是大于1的。
    最后把坐标还原回来即可。

    代码:

    /*************************************************************************
        > File Name: la3708.cpp
        > Author: jiangyuzhu
        > Mail: 834138558@qq.com 
        > Created Time: Sat 18 Jun 2016 03:22:49 PM CST
     ************************************************************************/
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<stack>
    using namespace std;
    typedef pair<int, int>p;
    const int maxn = 1e3, mod = 1e9 + 7, oo = 0x3f3f3f3f;
    int main (void)
    {
        int n, m;
        while(~scanf("%d%d", &n, &m)){
            double ans = 0;
            for(int i = 1; i < n; i++){
                double pos = (double)i / n * (n + m);
                ans += fabs(pos - floor(pos + 0.5));
            }
            ans = ans / (n + m) * 10000;
            printf("%.4f
    ", ans);      
        }
    }
  • 相关阅读:
    HQ-day17 CSS样式表基础①
    SQL 常用操作
    EXCEL 批量生成SQL
    js 顺序提交表单
    js 页面回调函数
    C# excel 常用操作
    C#关于LINQ
    JS 表单验证
    关于Cookie
    js 短信验证码功能
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758617.html
Copyright © 2020-2023  润新知