杂题:求 和不小于K的连续子数组的最短长度/长度不大于M的连续子数组最大和
862. 和至少为 K 的最短子数组
题意:
给定一个长度为 (n) 的数组 (A) ,(-10^5leq A_ileq10^5),要求出 和不小于 (K) 的连续子数组的最短长度。
解:
无非是双指针,右指针一直往右扫,左指针在适当的时候右移
当 (sum=0) 时,设置左指针为当前位置的下一位置;
当 (sum>=K) 时,加一些判断,使左指针适当右移。
之前做过一样的题,但是卡在了左指针右移上,一直处理不好。然后这次遇上了还是不会T^T。看了题解,记下来吧。
代码:
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
using namespace std;
const int mod=998244353;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e6+5;
int n,lim;ll a[maxn];
int solve()
{
int sum=0,st=1,res=inf;
for(int i=1;i<=n;i++)
{
if(a[i]>=lim)return 1;
sum+=a[i];
if(sum<=0){
sum=0;
st=i+1;
continue;
}
for(int j=i-1;a[j+1]<0;j--){
a[j]+=a[j+1];
a[j+1]=0;
}//!!!!!!!!
if(sum>=lim){
while(sum-a[st]>=lim||a[st]<=0)sum-=a[st++];
res=min(res,i-st+1);
}
}
return res==inf?-1:res;
}
int main()
{
scanf("%d%d",&n,&lim);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
printf("%d
",solve());
}
P1714 切蛋糕
题意:
给定一个长度为 (n) 的数组 (A) ,(-500leq A_ileq500),要求出 。长度不大于 (M) 的连续子数组的最大和。
解:
代码:
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
using namespace std;
typedef long long ll;
const int maxn=1e6+2;
const int mod=1e9+7;
int a[maxn];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int sum=0,st=1,res=0;
for(int i=1;i<=n;i++)
{
sum+=a[i];
if(sum<=0){
sum=0;st=i+1;
continue;
}
for(int j=i-1;a[j+1]<0;j--){
a[j]+=a[j+1];
a[j+1]=0;
}
while(i-st+1>m||a[st]<=0)sum-=a[st++];
res=max(res,sum);
}
printf("%d
",res);
}