蚂蚱跳跃问题

来源:互联网 发布:小米miui8免费网络短信 编辑:程序博客网 时间:2024/04/28 05:22

蚂蚱跳跃问题

题目大意:
一个蚂蚱最初位于坐标轴的原点,现在蚂蚱要跳跃到坐标轴的s点,跳跃规则是蚂蚱既可以往正方向跳跃,也可以往负方向跳跃,蚂蚱第一次跳跃1个单位,以后的跳跃步数在前一步的基础上加一。现在求蚂蚱跳跃到s点最少需要多少步数?
原题截图如下:
这里写图片描述

题意分析:

首先看题目的数据最大约为10亿,意味着不可能采用搜索、暴力等一些耗时的解决办法,也不会让你在代码中开辟较大的数组,那么拿到这个问题如何去解决呢?

初步分析

  1. 假如S为负,则只需求正S的结果

  2. 如果目标点S恰好能等于S = F(n) =(n(n+1))/2 , 说明最少只要经过n步就可以准确到达S点

  3. S一定介于F(n)与F(n+1)之间,即 F(n) <= S <= F(n+1)

进一步分析 :

  1. 问题其实就是求一个序列1,2,3,…… , m-1, m的和要为S,其中这些数可正可负

  2. 既然S = 1(-1) + 2(-2) + … … + m(-m)那么蚂蚱必须至少要经过n步(因为F(n) <= S)才能使得步数之和为S

  3. 假如所蚂蚱经过n步到达F(n)点,那么它下一步跳跃n+1个单位到达F(n+1)点,记 d = F(n+1) - S,

    如果d为偶数,那么一定存在一个数(1=< k <= n)使得 2*k = d , 也就是说 S = 1+2+…..+ n + (n+1)-d

    即S = 1 + 2 + …+(-k) + ….+ n +(n+1),从而可以知道只要再走一步就可以实现1—n+1个不同符号的数相加和为S.

    假如 d为奇数,那么在1到n之间不可能有一个数的倍数为d,那么可以再走一步得F(n+2)- S =

    d2,如果d2为偶数,就得解,,否则就再走一步F(n+3) - S = t3,

    t2和t3一定有一个数为偶数,,问题就得解了,所以当d为奇数的时候要么再n的基础上再走两步,要么再走三步

具体代码实现如下:

/**得到第T步的位置**/long result(int t){    return (t*(t+1))/2;}/**得到位置X的临近点步数**/getPos(long x) {    int t = floor(sqrt(2*x));    int r = t + 2;    while(t < r){        if(result(t) > x){            return t -1;        }        if(result(t) == x){            return t;        }        t++;        }    return 0;}/**求解到达x的最少步数**/int solve(int x){    x = abs(x);    int left = getPos(x);    int leftResult = result(left);    if(leftResult == x) return left;    if((leftResult+left+1-x)%2 == 1){        return (left + 2)%2 == 1 ? left + 2 : left + 3;    }else{        return left + 1;    }}

虽然测试用例都通过,但是还是不知道能不能AC啊,昨天笔试时间短,竟然都没想出什么解法。。。

0 0
原创粉丝点击