栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

题161.洛谷P3131 前缀和与差分-Subsequences Summing to Sevens S

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

题161.洛谷P3131 前缀和与差分-Subsequences Summing to Sevens S

文章目录
  • 题161.洛谷P3131 前缀和与差分-Subsequences Summing to Sevens S
  • 一、题目
  • 二、题解


题161.洛谷P3131 前缀和与差分-Subsequences Summing to Sevens S
一、题目

二、题解

看到这题,开局便想着我应该构建个前缀和数组,然后去用两个循环去求出满足被7整除的区间前缀和,但是这又毫无意外的超时了。以下是那个超时代码:

#include 

using namespace std;

int N;
int a[50010];
int sum[50010];

int main()
{
    cin>>N;
    for(int i=1;i<=N;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    int maxlen=0;
    for(int l=0;l 

于是我们想着如何将循环再去掉一层这样去优化它。有个定理是这样的,(a-b)%c=0=>a%c=b%c,正好这里我们用前缀和数组去求区间和的方式便是sum[r]-sum[l],所以要使得(sum[r]-sum[l])%7=0对应的区间长度最大,即得到sum[l]%7=sum[r]%7,r-l值最大就好。所以关键是记录下相同余数开始出现的位置与最后出现的位置,找到他们最大差值出来就好。AC代码如下:

#include 

using namespace std;

int N;
int a[50010];
int sum[50010];
int pre[7],post[7];

int main()
{
    cin>>N;
    for(int i=1;i<=N;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=(sum[i-1]+a[i])%7;//因为只要知道余数的情况,所以直接存前缀和与7的余数就好
    }
    for(int i=N;i>=0;i--)//倒着扫,找正序第一次出现的各个余数的位置
    {
        pre[sum[i]]=i;
    }
    for(int i=0;i<=N;i++)//正着扫,找正序最后一次出现的各个余数的位置
    {
        post[sum[i]]=i;
    }
    //切记上面两个循环都得扫到i=0,因为可能出现sum只有一个能被7整除的情况,这时候它的长度显然i-0,而不是不扫到i=0出现的i-i=0
    int maxlen=0;
    for(int i=0;i<7;i++)
    {
        maxlen=max(maxlen,post[i]-pre[i]);
    }
    cout< 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605032.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号