zoukankan      html  css  js  c++  java
  • UVALive.3708 Graveyard (思维题)

    UVALive.3708 Graveyard (思维题)

    题意分析

    这标题真悲伤,墓地。
    在周长为1e4的圆周上等距分布着n个雕塑,现在要加入进来m个雕塑,最终还要使得这n+m个雕塑等距,那么原来的n个雕塑移动的最小距离是多少。

    W=W 依旧没思路,看了题解学习此种技巧。

    首先原先给出的n个雕塑中有一个假定不动。然后剩余的n-1的个雕塑移动到最近的目标点。目标点的定义如下:
    将原圆周等距分为n+m份,每一份的分界点为一个位置,即目标点。那么难点就在于如何判断是最近的呢,这里用到的方法就是按比例扩大+下取整

    刚才说过分为n+m份,那么我们规定那个不动的雕像为0,其他的目标点,依次标记为1,2,3……(n+m-1)。然后按照这样的比例,标记出原先的n个点的位置。这样的标记实际上已经完成了比例的放大,放大比为原来:现在 = 1:(n+m).

    放大完成后,我们只需要求出原来和现在的位置差多少就行了:
    原来第i个雕塑的位置为
    pos = i / n * (n+m) ps:要放大n+m倍
    然后要移动到的目标点是 floor(pos + 0.5 )
    这两者差的绝对值,就是需要在圆周上移动的比例,注意这里是比例,不是实际的距离,也就是说最后在输出的时候还需要乘1e4.

    为何+0.5在下取整就是目标点呢?
    不放假设,有一个雕塑在1.01, 其+0.5后为1.51, 下取整完为1,即离它最近的应该是1那个目标点;在比如说有一个雕塑在1.49,+0.5后为1.99,离它最近的也是1那个目标点,而不是2. 不难看出+0.5在下取整是求最近的目标点。

    最后,将求出的比例累加,再乘1e4输出即可,注意保留4位小数。

    代码总览

    #include <cstdio>
    #include <cmath>
    using namespace std;
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m) != EOF){
            double pos = 0,ans = 0;
            for(int i =1; i<n; ++i){
               pos = 1.0*i/n *(n+m); ans += fabs(pos -floor(pos+0.5))/(n+m);}
            printf("%.4f
    ",ans*10000);
        }
        return 0;
    }
  • 相关阅读:
    A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
    Fliptile 开关问题 poj 3279
    Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276
    Aggressive cows 二分不仅仅是查找
    Cable master(二分题 注意精度)
    B. Pasha and String
    Intervals poj 1201 差分约束系统
    UITextField的快速基本使用代码块
    将UIImage转换成圆形图片image
    color转成image对象
  • 原文地址:https://www.cnblogs.com/pengwill/p/7367132.html
Copyright © 2011-2022 走看看