51nod-1615: 跳跃的杰克

【传送门:51nod-1615


简要题意:

  一个人站在坐标轴原点,可以向左或者向右跳,第一次跳一格,第二次跳两格(以此类推)

  求出最少的跳跃次数,使得这个人刚好落在(x,0)


题解:

  高一师兄出的模拟赛的第一题

  这道题很玄学,比赛的时候瞎想做出来了

  其实x为正为负是没有关系的,我们取绝对值,当作正数来做就好了

  首先假设答案为x,往左走为负数,往右走为正数

  那么其实走的方法就是1到x的序列,有的为正,有的为负

  比如12 答案为7

  原本的序列是1 2 3 4 5 6 7,总共为28

  但是我们要走到12,距离28为28-12=16

  这时候我们就要将序列里的一些数改为负数,而改变一个数的正负,带来的效益是偶数

  比如把1变成-1,就是-1 2 3 4 5 6 7,总共为26

  所以实际上是改变了和为16/2=8的一些数的正负,比如1 2 5或者2 6

  我们发现只要原本序列的和-x为偶数的话,就说明可以走到x

  那就简单了,二分找到最小的序列的和>=x,然后找到原本序列的和-x为偶数的序列就可以了


参考代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
int main()
{
    LL n;
    scanf("%lld",&n);n=abs(n);
    LL l=0,r=4*n,ans;
    while(l<=r)
    {
        LL mid=(l+r)/2;
        if(mid*(mid+1)/2>=n)
        {
            ans=mid;
            r=mid-1;
        }
        else l=mid+1;
    }
    while((ans*(ans+1)/2-n)%2!=0) ans++;
    printf("%lld
",ans);
    return 0;
}

 

原文地址:https://www.cnblogs.com/Never-mind/p/8819923.html