题解:P12892 [蓝桥杯 2025 国 Java B] 弹跳鞋
题解:P12892 [蓝桥杯 2025 国 Java B] 弹跳鞋
Link
二分、数学。
设其充能 \(x\) 次能跳的距离为 \(S\)。每次距离为 \(x,x-1,x-2, \cdots,1\),因此其总和为 \(S=\sum^{x-1}_{i=0}(x-i)=\frac{x(x-1)}{2}\)。因为最后总会跳到 \(L\) 的位置,所以 \(L\) 必定为 \(S\) 中一个或几个项的相反数的和,并且他们都必须为 \(2\) 的倍数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll l;
int main(){
cin>>l;
if(l==0) cout<<0;
for(int i=1;;i++){
if((i*(i+1))/2>=l&&((i*(i+1))/2-l)%2==0){
cout<<i<<endl;
return 0;
}
}
return 0;
}
于是打了个暴力,发现只有 \(60\) 分。发现此题还需要二分优化。
综上,该问题可以转化为:二分查找 \(x\),答案即为第一个满足 \(\frac{x(x+1)}{2} \ge L\),接着再向上寻找与 \(L\) 奇偶性相同的数即可。
// AC code.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
int main(){
cin>>n;
ll l=1,r=2e9;
while(l<r){
ll mid=(l+r)/2;
if((mid*(mid+1))/2>=n) r=mid;
else l=mid+1;
}
while(((l*(l+1))/2)%2!=n%2) l++;
cout<<l;
return 0;
}
//java
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
long n=sc.nextLong();
long l=1,r=2e9;
while(l<r){
long mid=(l+r)/2;
if ((mid*(mid+1))/2>=n) r=mid;
else l=mid+1;
}
while (((l*(l+1))/2)%2!=n%2) l++;
System.out.println(l);
}
}