题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3562
题目大意:有n个正整数组成一个序列,给定整数S,求长度最短的连续序列,使得它们的和大于或等于S。输出最短序列的长度。
解题关键:
(1) 前缀和B[i]=A[i]+A[i-1]+.........+A[1], A[i]+A[i+1]+.......+A[j]=B[j]-B[i-1]
(2)由于A[i]为正整数,B[i]单调上升,B[j]-B[i-1]>=S -——>B[i-1]<=B[j]-S,i越大,j-i+1越短——>问题转换成找使得B[i-1]<B[j]-S的
最大i,由单调性,可得到二分找下界的策略。
import java.util.*;
public class Main {
/**
* @param args
*/
static int[] num=null;
static int[] B=null;
static int lower_bound(int[] B,int j,int target)
{
int begin=0,end=j-1,mid;
while(begin<end)
{
mid=begin+(end-begin)/2;
if(target<=B[mid])
{
end=mid;
}
else
{
begin=mid+1;
}
}
return begin;
}
static int min(int a1,int a2)
{
return a1<=a2?a1:a2;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int n=0,sum,ans=0;
Scanner in=new Scanner(System.in);
while(in.hasNext())
{
n=in.nextInt();
sum=in.nextInt();
num=new int[n+1];
B=new int[n+1];
for(int i=1;i<=n;i++)
{
num[i]=in.nextInt();
B[i]=B[i-1]+num[i];
}
ans=n+1;
for(int i=1;i<=n;i++)
{
int j=lower_bound(B,i,B[i]-sum);
if(j>0) ans=min(ans,i-j+1);
}
System.out.println((ans==n+1?0:ans));
}
}
}