有环,易想到复制一份在后面,然后考虑枚举起点,尺取法双指针扫描即可,复杂度为线性。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int t;
int n,k;
int a[maxn],b[maxn],c[maxn<<1];
int main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=1;i<=n;i++)
{
c[i]=a[i]-b[i];
c[n+i]=a[i]-b[i];
}
int l=1,r=1;
ll tem=0;
bool ok=true;
while(l<=n&&r-l+1<=n)
{
if(!ok) break;
if(tem+c[r]+k>=0)
{
tem+=c[r];
r++;
}
else
{
tem+=c[r];
r++;
while(tem+k<0)
{
tem-=c[l];
l++;
if(l>r)
{
ok=false;
break;
}
}
}
}
if(!ok||l>n) cout<<-1<<endl;
else cout<<l<<endl;
}
return 0;
}
类似题,Poj 3061
AC代码如下:
#include<iostream>
#include<cstdio>
//#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int t,n,s;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&s);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int l=1,r=1;
int tem=0;
int ans=100005;
while(r<=n+1&&l<=r)
{
if(tem<s)
{
tem+=a[r];
r++;
}
else
{
ans=min(ans,r-l);
while(tem>=s&&l<r)
{
ans=min(ans,r-l);
tem-=a[l];
l++;
}
}
}
if(ans==100005) cout<<0<<endl;
else cout<<ans<<endl;
}
return 0;
}