UVa 846 - Steps

来源:互联网 发布:长沙网络危机公关公司 编辑:程序博客网 时间:2024/04/28 19:32

传送门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;}



0 0
原创粉丝点击