前缀和的应用(Subsequences Summing to Sevens S)

给你n个数,分别是a[1],a[2],...,a[n]。求一个最长的区间[x,y],使得区间中的数(a[x],a[x+1],a[x+2],...,a[y-1],a[y])的和能被7整除。输出区间长度。若没有符合要求的区间,输出0。

做这个题目需要知晓一个定理:若两个数相减后除以n的余数等于零,那么这两个数分别除以n的余数一定相同。那么思路就很明显了,我们可以反过来应用这个定理,把前缀和求出之后全部除以7保留余数,那么余数相同的两个前缀和相减除以7的余数就等于0,也就是可以被7整除。

#include<iostream>
using namespace std;
#define N 1000100
int n,q[N],pre[7],las[7];//pre数组用来记录余数在数组第一次出现的位置,las数组记录最后一次出现的位置
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>q[i];
        q[i]=(q[i]+q[i-1])%7;
    }
    for(int i=1;i<=n;i++)//从头到尾遍历,那么最后一次更新的位置就会被记录在las数组中,也就是余数最后一次出现的位置
        las[q[i]]=i;
    for(int i=n;i>=0;i--)//从尾到头遍历,那么最后一次更新的位置就会被记录在pre数组中,也就是余数第一次出现的位置
        pre[q[i]]=i;
    int maxn=0;
    for(int i=1;i<7;i++)
        maxn=max(las[i]-pre[i],maxn);
    cout<<maxn;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值