zoukankan      html  css  js  c++  java
  • ZOJ 1871. Steps

        ZOJ 1871: Steps

        地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=871

        题意:假设在一条直线上标记着数字刻度。每一步的步长不能为负数,且和前一个步长的关系必须是相等,或大于或小于1。第一步和最后一步的步长必须是1。则从 x 到 y 的最小步数是多少。

        可以用数学语言重新描述题目如下:给出无符号整数 d ( =  y-x ) ,可分解为满足下列条件的 n 个正整数的和,求 n 的最小值:

         d = ∑ Si ; (i = 1 ... n)

       

        且满足:

        S1 = Sn = 1;

        | S(i + 1) - Si | ≤ 1;

        分析:根据题目要求,理想条件下,为了达到最小步数,步长变化应该是从1,2,3 ... 一直增加到最大值 M,然后逐渐减小到1:

        distance = y - x ;

        distance = 1 + 2 + 3 + ... + M + ... + 3 + 2 + 1 = M^2;

        steps = 2 * M - 1;  (步数)

        

        因此如果距离正好是一个平方数(M 的平方),则步数一定是(2M-1),其中 M 为 最大步长。当距离不是平方数时,假设介于 M^2 和 (M+1)^2 之间,则

        distance = M^2 + remain; (0 < remain <= 2M )

        

        remain 是平方数后的尾数,如果remain 小于等于 M,则我们只需要把一个 remain 的步长插入到前面的序列中即可。如果 remain 大于 M,则一步是不够的,我们至少需要插入两步,M 和 remain - M(当然,也可以是 remain/2 和 remain - remain/2)。因为我们不能插入大于 M 的步长,否则最终累加的和会达到下一个平方数((M+1)的平方)。

        因此根据上述分析,代码如下(代码中为了可读性,M 用 maxStep 表示):

    code_zoj1871
    #include <stdio.h>
    #include <math.h>
    int main(int argc, char* argv[])
    {
        unsigned int x = 0, y = 0;
        unsigned int distance, maxStep, remain, steps;
        while(scanf("%lu %lu", &x, &y) != EOF)
        {
            distance = y - x;
            if(distance == 0)
            {
                printf("0\n");
                continue;
            }
            maxStep = (unsigned int)sqrt(distance);
            remain = distance - maxStep * maxStep;
    
            steps = maxStep * 2 - 1;
            if(remain > 0)
            {
                if(remain <= maxStep)
                    steps++;
                else
                    steps += 2;
            }
            printf("%lu\n", steps);
        }
        return 0;
    }
  • 相关阅读:
    力扣(LeetCode)验证回文串 个人题解(C++)
    力扣(LeetCode)平方数之和 个人题解
    Exclusive Access 2 UVA
    C语言中指针*p[N], (*P)[N]的区别
    2018年蓝桥杯国赛比赛心得
    2018acm/icpc西安邀请赛比赛心得
    [最小割]Cable TV Network UVA
    Tree Reconstruction UVA
    Twenty Questions UVA
    python中的enumerate 函数(编号的实现方式)
  • 原文地址:https://www.cnblogs.com/hoodlum1980/p/2521060.html
Copyright © 2011-2022 走看看