二分 —— 基本算法刷题路程

发布于:2025-04-09 ⋅ 阅读:(93) ⋅ 点赞:(0)

一、1.求阶乘 - 蓝桥云课

算法代码:

#include <bits/stdc++.h>
using namespace std;
#define  ll long long
ll check(ll n)
{
    ll cnt=0;
    while(n)
    {
        cnt+=(n/=5);
    }
    return cnt;
}

int main()
{
    ll k;
    cin>>k;
    ll L=0,R=1e19;
    while(L<R)
    {
        ll mid=(L+R)>>1;
        if(check(mid)>=k)
        {
            R=mid;
        }
        else
        {
            L=mid+1;
        }
    }  
    if(check(R)==k)
    {
        cout<<R;
    }
    else
    {
        cout<<-1;
    }
    return 0;
}

二、1.青蛙过河 - 蓝桥云课

 

算法代码: 

#include <bits/stdc++.h>
using namespace std;
int n,x;
int h[100005];
int sum[100005];

bool check(int mid)
{
    for(int i=1;i<n-mid+1;i++)
    {
        if(sum[i+mid-1]-sum[i-1]<2*x)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    cin>>n>>x;
    sum[0]=0;
    for(int i=1;i<n;i++)
    {
        cin>>h[i];
        sum[i]=sum[i-1]+h[i];
    }
    int L=1,R=n;
    while(L<R)
    {
        int mid=(L+R)/2;
        if(check(mid))
        {
            R=mid;
        }
        else
        {
            L=mid+1;
        }
    }
    cout<<L;
    return 0;
}

三、1.管道 - 蓝桥云课

算法代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int LEN=1e9;
int n,len;
int L[N],S[N];

bool check(int t)
{
    int cnt=0;
    int last_L=2,last_R=1;
    for(int i=0;i<n;i++)
    {
        if(t>=S[i])
        {
            cnt++;
            int left=L[i]-(t-S[i]);
            int right=L[i]+(t-S[i]);
            if(left<last_L)
            {
                last_L=left,last_R=max(last_R,right);
            }
            else if(left<=last_R+1)
            {
                last_R=max(last_R,right);
            }
        }
    }
    if(cnt==0)
    {
        return false;
    }
    if(last_L<=1&&last_R>=len)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int main()
{
    scanf("%d%d",&n,&len);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&L[i],&S[i]);
    }
    int LL=0,R=2e9,ans=-1;
    while(LL<=R)
    {
        int mid=((R-LL)>>1)+LL;
        if(check(mid))
        {
            ans=mid,R=mid-1;
        }
        else
        {
            LL=mid+1;
        }
    }
    printf("%d\n",ans);
    return 0;
}

 四、1.技能升级 - 蓝桥云课

算法代码: 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;    // Note: long long is needed
const int N = 100100;
int a[N], b[N];    // Store a_i, b_i
int n, m;

bool check(ll mid) {    // Check if the last skill upgrade can reach mid
    ll cnt = 0;
    for (int i = 0; i < n; ++i) {
        if (a[i] < mid)
            continue;    // Initial value of skill i is less than mid, skip
        cnt += (a[i] - mid) / b[i] + 1;    // Number of times skill i is used
        if (cnt >= m)    // Total upgrades ≥ m, mid is too small
            return true;
    }
    return false;    // Total upgrades < m, mid is too large
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
        cin >> a[i] >> b[i];
    ll L = 1, R = 1000000;    // Binary search for the highest possible last attack
    while (L <= R) {
        ll mid = (L + R) / 2;
        if (check(mid)) L = mid + 1;    // Increase mid
        else R = mid - 1;    // Decrease mid
    }
    ll attack = 0;
    ll cnt = m;
    for (int i = 0; i < n; ++i) {
        if (a[i] < R) continue;
        ll t = (a[i] - L) / b[i] + 1;    // Number of upgrades for skill i
        if (a[i] - b[i] * (t - 1) == R)
            t -= 1;    // If skill's upgrade equals R exactly, other skills are better
        attack += (a[i] * 2 - (t - 1) * b[i]) * t / 2;
        cnt -= t;
    }
    cout << attack + cnt * R << endl;
    return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到