UVa 846 - Steps

本文介绍了解决UVa846 Steps问题的方法,该问题是计算从一个距离到另一个距离所需的最少步数,每一步长度从1开始并以1结束。通过找到最接近距离差的对称序列,并计算剩余距离,最终确定额外所需步数。

传送门UVa 846 - Steps

跟前面的一题有些类似.

题意是给出两个距离, 求从一个到另一个需要走的步数.

每一步走的距离必须从1开始, 以1结束, 可以大于, 等于, 或小于上一步.

我的算法是求出小于距离之差n的最大距离dis, 相减得到一个数k, 这个数就是还需要走的距离. 对(k / 最大一步距离)向上取整, 结果就是另外要多走的步数.

先来看看dis = 1 + 2 + ..i + (i + 1) + i... + 2 + 1这个式子. i + 1是最大一步距离.如果忽略其他条件的话, 这个是"对称"的, 他的值就是i(i + 1)  + (i + 1)

联系题目, 我们所要做的无非就是在这个式子中插入距离num (num <= max), 使之结果等于差值n.

n - dis, 得到的值就是要插入的距离k. 所以只要距离k / max, 结果向上取整就行, 得到还要额外走的步数.


上面的描述太混乱了...再用最简单的语句说一遍我的思路: 

求出最接近距离之差的1 + 2 +....+ i + (i + 1)+ i + ... + 2 + 1, 再把他们的差除以i, 向上取整得到值a

最后的答案就是a + i * 2 + 1

详情见代码


#include <cstdio>
#include <cmath>

using namespace std;

int main()
{
    //freopen("input.txt", "r", stdin);
    int T;
    double n, sum, tempsum;
    double a, b;
    int i, cnt;
    scanf("%d", &T);
    while (T--)
    {
        bool flag = false, sflag = false;
        i = 1;
        scanf("%lf%lf", &a, &b);
        n = abs(a - b);
        if ((int)n == 3)        //首先排除几种特殊情况
        {
            printf("3\n");
            continue;
        }
        else if ((int)n == 0)
        {
            printf("0\n");
            continue;
        }
        else if ((int)n == 1)
        {
            printf("1\n");
            continue;
        }
        else if ((int)n == 2)
        {
            printf("2\n");
            continue;
        }
        while (true)
        {
            tempsum = i * (i + 1) + (i + 1);    //储存暂时的数据, 因为我们要的是不超过n的最大sum
            if (tempsum <= n)
            {
                sum = tempsum;
                flag = true;
                i++;
            }
            else
            {
                if (flag)
                    i--;
                break;
            }
        }
        cnt = i * 2 + 1 + ceil((n - sum) / (i + 1));
        printf("%d\n", cnt);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值