您的位置:首页 > 产品设计 > UI/UE

POJ-3061 Subsequence(尺取法)

2016-01-02 17:02 357 查看
题意:给你一个长度为n的序列,然后求连续序列中sum不小于s的最短长度。

第一种方法。前缀和。然后二分枚举求得长度复杂度为nlogn

const int maxn=100100;
int a[maxn];
ll sum[maxn];

int main()
{
int T;
cin>>T;
while(T--)
{
int N,S;
cin>>N>>S;
clr(sum);
for(int i=1;i<=N;i++)
{
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
if(sum
<S) cout<<0<<endl;
else
{
int len=maxn;
for(int i=0;sum[i]+S<=sum
;i++)
{
int res=lower_bound(sum+i,sum+N,sum[i]+S)-sum;
len=min(len,res-i);
}
cout<<len<<endl;
}
}
return 0;
}


第二种方法,尺取法。

自己先用队列模拟写了一个
const int maxn=100100;

long long sum[maxn];
long long num[maxn];

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
clr(sum);
int N,S;
scanf("%d%d",&N,&S);
for(int i=1;i<=N;i++) scanf("%lld",&num[i]);
int cnt=1;
ll sum=0;
int len=INF;
queue<ll> q;
while(cnt<=N)
{
while(sum<S)
{
q.push(num[cnt]);
sum+=num[cnt];
cnt++;
//cout<<sum<<endl;
if(cnt>N) break;
}
if(sum<S) break;
int L=q.size();
len=min(len,L);
while(sum>=S&&!q.empty())
{
sum-=q.front();
q.pop();
if(sum>=S)
{
int L=q.size();
len=min(len,L);
}
}
}
cout<<(len==1e9?0:len)<<endl;
}
return 0;
}


觉得不精练。

const int maxn=100100;

int a[maxn];

int main()
{
int T,N,S;
cin>>T;
while(T--)
{
cin>>N>>S;
for(int i=1;i<=N;i++) cin>>a[i];
int res=N+1;
int s=1,t=1,sum=0;
for(;;)
{
while(s<=N&&sum<S) sum+=a[s++];
if(sum<S) break;
res=min(res,s-t);
sum-=a[t++];
}
cout<<(res==N+1?0:res)<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: