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\n",ans); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚