小兔蹦蹦跳 腦洞

2022-08-16 09:09:07 字數 1856 閱讀 7326

小兔位於x軸的x點,欲跳至x軸的y點。x,y均為整數。小兔每次沿x軸直線跳躍,每跳的長度均為正整數,假設

小兔一共跳了n次才到目的地,每次跳的長度為f1,f2,..., fn. 有規則如下:

f1=fn=1

|fi-fi-1|<=1   , 2<=i<=n         (注:| |是絕對值符號)

我們的問題是給定x,y, 如何使得n最小。

包含多組資料,但不超過1000組。每組資料一行,每行包括兩個整數x和y。0 <= x < y <= 1000000000 。

對於每一組資料,輸出一行,即從x到y的最小跳躍次數n。

45 4845 4945 50

334這道題出的非常好,我一點思路也沒有。

先理解清楚題意,第一步和最後一步都只能跳1,且相鄰跳躍次數相差不能大於1

我覺得畫個草圖能好理解點:

圖上格仔高度代表一次跳躍的長度,那麼列格仔數量就代表跳了幾次,顯然這樣格仔的總面積代表跳躍的距離。這樣畫的好處就是能很好看出第一步和最後一步只跳1。f(n)代表最高格仔為按上圖形式跳時的跳躍距離,其實還需要用到f(n)的遞推式。

f(n)=f(n-1)+n+n-1=f(n-1)+2n-1。而且n對應的跳躍次數為2n-1。

這樣或許就好理解點了,想想看,上圖是最對稱最完美的跳躍方式,跳躍距離還都是平方數(感覺挺神奇的)。f(n)與f(n-1)差2n-1,也就是在f(n-1)~f(n-1)+2n-1的範圍內都是n-2是最大的跳躍數。用個例子說明一下:

比如f(4)=16,f(3)=9。當距離為10時,9<10<16,易知此時「最高峰(最高的格仔)「只能到3,而f(3)=9,還差1,那麼好辦,只需在高度為1的格仔旁邊再放乙個高度為一的格仔就能滿足要求,這樣也會多跳一回,所以最小跳躍次數就為(10-9)+2*3-1=6;

而當距離為15時,15-9=6>3,顯然,這比「最高峰「還要大,所以一次是跳不完的,那就跳兩次,也就是在高度為3的格仔旁放置兩個高度為3的格仔。當距離再大時,最高的格仔就應該為4了,問題又可以同樣處理了。因此得到問題的答案:

(pos相當於上述n,len為距離)

#include#include

#include

#include

#include

using

namespace

std;

const

int maxn=1e9+10

;int a[100050];

intmain()

ints,t;

while(scanf("

%d%d

",&s,&t)==2

)

}len-=a[pos];

int ans=2*pos-1

;

if(len==0) printf("

%d\n

",ans);

else

if(len<=pos) printf("

%d\n

",ans+1

);

else printf("

%d\n

",ans+2

); }

return0;

}