尺取
一:定义两个端点i,j, 初始化都从最左当开始;
二:j向右移动,i保持不动;直到i与j之间数(包括i,j)的和>=m,记录此时的区间长度
三:j停止移动,i向后移动,直至不满足条件(即i与j之间都和<m),记录i-1到j的区间长度。
四:然后j继续向后移动,i不变,重复上述步骤,直至如果j点=移动到区间末尾i~j区间的和还不大于等于m,结束区间的枚举。
五:可以用打擂台的方式找出满足条件的最小区间;
#include<stdio.h>
int main()
{
int n,m,i,j,sum,a[100],k1=0,x;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",a+i);
sum=i=j=0;x=n;
while(1)
{
while(sum<m&&j<n)
{
sum+=a[j];
j++;
}
if(j-i<x)
x=j-i;
if(sum<m)
break;
while(sum>=m)
{
sum-=a[i];
i++;
}
if(j-i<x)
x=j-i+1;
}
printf("%d",x);
return 0;
}
或者(两个代码大同小异)
#include<stdio.h>
int main()
{
int n,m,i,j,sum,a[100],k1=0,min;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",a+i);
sum=i=j=0;x=n; //先使i,j=0,相当于都从最左边开始,min=n,使n当擂主
while(1)
{
while(sum<m&&j<n)
{
sum+=a[j];
j++;
}
if(j-i<min)
min=j-i; //记录最小长度
if(sum<m)
break;
sum-=a[i]; //i向右移一位,在回头判断sum是否<m
i++;
}
printf("%d",min);
return 0;
}