zoukankan      html  css  js  c++  java
  • 【数学+思维】ZZULIOJ 1531: 小L的区间求和

    题目链接

    • 题目描述
    在给定的一个整数序列中,小L希望找到一个连续的区间,这个区间的和能够被k整除,请你帮小L算一下满足条件的最长的区间长度是多少。
    输入
    第一行输入两个整数n、k。(1 <= n <= 105,1<=k<100)
    接下来一行输入n个整数,表示序列中的数。
    输出
    输出一个整数,满足条件区间的最长长度,如果不存在,输出0
    • 样例输入
    5 7
    1 2 4 1 1
    • 样例输出
    3

    题解:
    先将数组的前缀和数组构建起来。在构建过程中模K,所以此时前缀和数组中所有数属于[0,K-1],假如有两个位置i,j,前缀和数组pre[i] == pre[j],那么不模K的前缀和数组 pre[j]-pre[i]的结果一定是K的倍数,j-i就是长度。
    所以我们的目的就成不断的了找:pre[i] == pre[j],保存长度 = j-i并更新。下面代码用:map首先都初始化为-1,之后遍历过程中遇到了就记录pre[i]的值第一次出现的位置


    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int NN = 1e5;
    
    int N,K;
    int a[NN+10];//源数组 
    int pre[NN+10];//前缀和数组 
    map<int,int> mp; //mp[n] = i 表示前缀和数组中数字n在位置i第一次出现 
    int main(){
        cin>>N>>K;
        for(int i =1;i<=N;i++){ //读入数据 
            scanf("%d",&a[i]);
        }    
        for(int i = 1;i<=N;i++){ //构建前缀和数组并取余K 
            pre[i] = (a[i]+pre[i-1])%K;
            mp[pre[i]] = -1;//都初始化为-1
        }
        int maxlen = 0; //最长长度 
        for(int i = 1;i<=N;i++){
            if(mp[pre[i]] == -1){  
                mp[pre[i]] = i;//改成第一次出现的位置 
            }else{
                maxlen = max(maxlen,i-mp[pre[i]]);//i是pre[i]此时的位置 mp[pre[i]]是pre[i]第一次出现的位置,两个相减为k的倍数 
            }
        }
        cout<<maxlen<<endl;
        return 0;
    }

     另一种用vector的写法,vector存前缀和数组元素出现的位置

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int NN = 1e5;
    
    int N,K;
    int a[NN+10];//源数组 
    int pre[NN+10];//前缀和数组 
    vector<int> ve[110];
    int main(){
        cin>>N>>K;
        for(int i =1;i<=N;i++){ //读入数据 
            scanf("%d",&a[i]);
        }    
        ve[0].push_back(0);
        for(int i = 1;i<=N;i++){ //构建前缀和数组并取余K 
            pre[i] = (a[i]+pre[i-1])%K;
            ve[pre[i]].push_back(i);
        }
        int maxlen = 0;
        for(int i = 0;i<K;i++){
            if(ve[i].size()>1)
                maxlen = max(maxlen,ve[i][ve[i].size()-1] - ve[i][0]); //最后一次出现的位置 - 第一次出现的位置 
        }
        cout<<maxlen<<endl;
        return 0;
    }


  • 相关阅读:
    springboot(eureka子项目)+idea+jsp 404问题
    什么是区块链以及他的6个特征?
    elasticsearch启动时提示内存不足错误的解决方法
    ElasticSearch 安装root用户启动失败问题解决
    防抖节流(立即执行和延时执行)
    将数字转为千分制格式(最简单)
    微信H5跳转任意小程序
    原生html+css设置项目主题色(超简单)
    H5获取手机型号
    css属性——env()和constant()设置安全区域
  • 原文地址:https://www.cnblogs.com/bigbrox/p/11347682.html
Copyright © 2011-2022 走看看