题解 题号1028 子序列

Subsequence(poj)

https://ac.nowcoder.com/acm/contest/20960/1028

  • 题目简述:
  • 给定 N 个正整数序列(10 < N < 100 000),每个正整数小于或等于 10000,并给出一个正整数 S(S < 100 000 000)。编写一个程序来查找序列中连续元素的子序列的最小长度,其总和大于或等于 S。

意思就是在一个数列中 找到一个最短的连续子序列,使其Sn恰好是大于给定的S的

  1. 那么我们可以采用双指针的方法
  2. 左指针l 用作for循环中 一次往右移动一下
  3. 右指针r 在while循环中:while(r <= n && sum < s)
  4. 这两个指针的移动形似蚯蚓
  5. 每一次for循环都要更新minlen和当前和sum的值

有两个注意的点:

  1. 由于题目输入的t可能大于1 所以新的轮次开始前要清空数组 memset(a,0,sizeof(a))
  2. minlen更新是if(sum >= s)的情况下才更新,不然循环跳出来有可能是r > n了,但sum并没有>s
using namespace std;
int a[100010];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--) //循环a次
    {
        int n,s;
        scanf("%d%d",&n,&s);
        memset(a,0,sizeof(a));
        for(int i = 1; i <= n; i++)
        {
            scanf("%d",&a[i]);
        }
            int sum = 0, r = 0; //r为右指针 l为左指针
            int minlen = n+1; //minlen的初始化值要总数n都大
            for(int l = 1; l <= n; l++)
            {
                while(r <= n && sum < s)
                {
                    r++; //r指针不断右移
                    sum += a[r];
                }
//                 cout<<l<<" "<<r<<" "<<sum<<endl;
                //while循环结束后 r所处的位置就是我们本次循环找到的临界位置
                if(sum >= s) //当sum大于s时 才更新minlen 
                	minlen = min(minlen, r-l+1);
                //当左指针l向右移动一位时 相应的sum就要减去这个数值
                sum -= a[l];
               
            }
        if(minlen > n) cout<<0<<endl;
        cout<<minlen<<endl;
    }
}

运行结果模拟:

alt

全部评论

相关推荐

_mos_:忍耐王
点赞 评论 收藏
分享
06-23 11:43
门头沟学院 Java
allin校招的烤冷面很爱看电影:我靠,今天中午我也是这个hr隔一个星期发消息给我。问的问题还是一模一样的😅
点赞 评论 收藏
分享
06-26 19:47
中南大学 Java
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务