尺取

尺取

一:定义两个端点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;
}
以上两个代码都不能让判断恰好n个数相加等于m的情况或者n个数相加小于m的情况