题解: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);
    }
}
posted @ 2025-06-22 18:58  M1_Byte  阅读(12)  评论(0)    收藏  举报