题解 | #小宝的幸运数组#

小宝的幸运数组

https://ac.nowcoder.com/acm/problem/217896

题意:找到一个数组中满足子数组之和可以被k整除的最大长度。

暴力:求一个前缀和然后两重循环判断每一个子数组能否被k整除,这里值得注意的是正向循环和逆向循环所形成的子数组集合是一样的所以选取一个方向即可。时间复杂度为O(n^2^) 优化:我们在用前缀和求是否能够被k整除所用的公式为(sum[r]-sum[l-1])%k=0? 根据同余定理我们可以知道只要满足sum[r]%k==sum[l-1]%k即可满足上述式子,由于是求最大长度,我们我们只要记录每个余数最先出现的位置,在后续的如果出现相同余数,子数组长度即为当前位置减去第一次出现位置,时间复杂度为O(n)

#include<bits/stdc++.h>
using namespace std;
int a[100001],b[100001];//b数组用来记录每种余数第一次出现的位置
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
          int n,k;
          scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
      for(int i=1;i<k;i++)b[i]=-1;
        b[0]=0;
        int res=-1;
        for(int i=1;i<=n;i++)
        {
            a[i]=(a[i-1]+a[i])%k;
            if(b[a[i]]!=-1)//如果之前存在这个余数,则是个合法数组
            {
                res=max(res,i-b[a[i]]);
                continue;
            }
            b[a[i]]=i;//没出现则记录
        }
        cout<<res<<endl;
     }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-15 17:09
点赞 评论 收藏
分享
求offer的大角牛:简历写的第一乱,没有突出重点,第二项目太多太杂看不出来有啥核心技术,第三自我评价太多了,第四获得的荣誉没啥含金量,可以不写,反正问题不少
点赞 评论 收藏
分享
06-24 19:27
云南大学 Java
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

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