• LA 2678


    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=679

      输入一个N,和一个S,第二行输入N的整数,要求的是由这N个数组成的数列中,一个连续的子数列的和大于或等于S时,这个子数列的长度最小是多少?

    解题报告:算法竞赛入门经典上的题,一开始用自己的思路去做,按照我的思路时间更短,但一直WA,不知道为什么,我的思路就是设置两个指针,一个指向子数列的开头的前一个,另一个指向子数列的最后一个,然后在循环条件j <= N的条件下,另外设一个sum 保存当前的子数列的和,然后判断如果当前子数列的和比S小,则将尾指针向后移动一位并将sum的值相应的增加,如果判断出来当前子数列的和比S大,则判断当前子数列的长度并且比较是否是最短的,然后将子数列的前指针向后移动一位,同时将sum的值减去相应的值,这样最后得出的长度最小的子数列的长度便是我们要的答案。但是不知道是有漏洞还是算法本来就不可行,交上去一直WA,麻烦如果知道的童鞋告诉我一下。然后看了大白书之后,有一种新的算法,我觉得没我的快,但结果是对的,没办法。他的做法是先预处理,求出从第一个数到第 i 个数的和并保存起来,然后只要枚举尾节点,然后内层再嵌套一个循环判断满足

    到这个尾节点的和大于等于S的前头节点最大的也就是长度最小的子数列。

    下面是我的错误代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 
     6 const int maxn = 100000;
     7 int A[maxn+5];
     8 
     9 int main()
    10 {
    11     int N,S;
    12     while(scanf("%d%d",&N,&S)!=EOF)
    13     {
    14         A[0] = 0;
    15         for(int i = 1;i <= N;++i)
    16         scanf("%d",&A[i]);
    17         int i = 0,j = 0,ans = 0x7ffffff,sum = 0;
    18         while(j <= N)
    19         {
    20             if(sum < S)
    21             sum += A[++j];   //当前子数列的和小于S时,尾节点向后移动,并加上后一个节点的值 
    22             else
    23             {
    24                 ans = min(ans,j - i); //当前子数列的和大于等于S时,先判断是不是长度最小的,然后再把前指针往后移动 
    25                 i++;
    26                 sum -= A[i];
    27             }
    28         }
    29         printf(ans>100000? "0":"%d
    ",ans);
    30     }
    31     return 0;
    32 }
    33                 
    View Code

    下面是AC的代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 
     6 const int maxn = 100000;
     7 int A[maxn+5];
     8 
     9 int main()
    10 {
    11     int N,S;
    12     while(scanf("%d%d",&N,&S)!=EOF)
    13     {
    14         A[0] = 0; 
    15         for(int i = 1;i <= N;++i)
    16         {
    17             scanf("%d",&A[i]);
    18             A[i] = A[i-1] + A[i];
    19         }
    20         int ans = 0x7ffffff,j = 0,flag = 0;
    21         for(int i = 1;i <= N;++i)
    22         if(A[i] - A[j] >= S)
    23         {
    24             while(A[i] - A[j+1] >= S) j++;
    25             if(i - j < ans)
    26             {
    27                 flag = 1;
    28                 ans = i - j;
    29             }
    30         }
    31         printf(flag? "%d
    ":"0
    ",ans);
    32     }
    33     return 0;
    34 }
    35             
    View Code
  • 相关阅读:
    java设计模式之适配器模式
    在Eclipse中建立Maven Web项目
    java设计模式之原型模式
    java设计模式之建造者模式
    java设计模式之工厂模式
    java设计模式之单例模式
    C# 前端多次上传文件
    C# async 和 await
    .NET 4.0 任务(Task)
    C# 5.0
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3344681.html
Copyright © 2020-2023  润新知