b_pat_火星购物(双指针+二分思想)

给定一个长度为n的砖石的价值序列和目标值m,你需要找到两个切分点 p1, p2,使得 [p1, p2] 中的数的总和尽量等于m,如果不等于m,找一个尽量小的总和代替

方法一:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int s[N];

int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n,m,l=0,ans=0x3f3f3f3f; cin>>n>>m;
    for (int i=1; i<=n; i++) cin>>s[i];
    for (int i=1; i<=n; i++) s[i]+=s[i-1];
    
    for (int r=1; r<=n; r++) {
        while (l<=r && s[r]-s[l+1]>=m) l++;     //如果这一段区间的值>m的话,证明需要缩减区间中的值
        if (s[r]-s[l]>=m) ans=min(ans, s[r]-s[l]);
    }
    l=0;
    for (int r=1; r<=n; r++) {
        while (l<=r && s[r]-s[l+1]>=m) l++;
        if (s[r]-s[l]==ans) printf("%d-%d\n", l+1, r);
    }    
    return 0;
}

复杂度分析

  • Time\(O(n)\)
  • Space\(O(n)\)
原文地址:https://www.cnblogs.com/wdt1/p/13684310.html