【蓝桥杯】数组中存在K倍区间的子数组个数

前言

蓝桥杯全国软件和信息技术专业人才大赛由工业和信息化部人才交流中心主办,每年参赛人数超过30000人。蓝桥杯大赛作为国内领先的全国性 IT 学习赛事,持续有力支撑综合测评、奖学金评定、升学考研,是高等教育教学改革和创新人才培养的重要竞赛项目。接上次算法解析,今天继续逐一从简到难安排解析各大编程算法题。
在这里插入图片描述

题目

给定一个长度为N的数列,A1, A2, … AN,如果其中一段连续的子序列Ai, Ai+1, … Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
输入格式
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
输出格式
输出一个整数,代表K倍区间的数目。
样例输入
5 2
1
2
3
4
5
样例输出
6

分析

1、根据题意我们可以确定问题是计算n个长度的数组中连续一个或多个元素之和是k倍的子数组个数,说直白点就是计算连续一个或多个元素之和是K的倍数,这些元素组成另一个数组,最后计算可以组合成满足规则的数组个数即可。比如题目数组{1,2,3,4,5} 5个元素可以组成被2整除的连续子数组6个。

算法

1、数组中每个元素都有可能被K整除,也都有可能与后续元素组成能够被K整除的集合,故我们必须保证每个元素要进行逻辑判断。那么,依次循环每个元素并验证即可以保证此步骤。
2、接上一步,每个元素先判断是否能被K整除,能够则可以组成一个元素的子数组,此时总的子数组+1;由于题目要求必须连续一个或几个元素之和是K的倍数,那么我们依次用当前元素与后续的所有元素进行组合,每组合一个元素则判断一次是否满足规则,满足规则总的子数组+1,不满足规则继续组合。
3、当每个元素全部依次与后续元素组合验证后,最后的总的子数组树即是我们这个数组能被K整除的所有情况。

难度

难度较为简单,星级 ★

实战

该题为蓝桥杯简单试题,我们本次实战用JAVA语言演示。题目输入5 2 则是5个元素的数组组成能够被2整除的子数组个数,后续12345则是数组元素;输出我们直接控制台打印,为保证测试效果我们每次都打印出满足规则的子数组。

1、创建算法

/**
 * k倍区间
 * @param n 数组长度
 * @param k 除数
 * @param array 数组
 * @author senfel
 * @date 2023/4/12 12:45 
 * @return int
 */
public static int compute(int n,int k,int[] array){
    int count = 0;
    if(array.length == 0 || array.length != n){
        return count;
    }
    //题目意思就是 n个元素的数组中连续元素之和为k的倍数一共有几组,一个元素为k倍也算
    for(int i=0;i<n;i++){
        if(array[i] % k == 0){
            //如果当前元素能够被k整除也算作一种
            count++;
            System.err.println("满足条件的集合:["+array[i]+"]");
        }
        //依次组合i+1到n个元素
        //每个组合sum
        int sum = array[i];
        String str = array[i]+"";
        for(int j = i+1;j<n;j++){
            sum+=array[j];
            str = str + "," + array[j];
            if(sum % k == 0){
                //多个连续元素组合能够被k整除
                count++;
                System.err.println("满足条件的集合:["+str+"]");
            }
        }
    }
   return count;
}

2、创建测试用例

@SpringBootTest
class DemoApplicationTests {

    /**
     * 计算K倍区间测试用例
     * @author senfel
     * @date 2023/4/12 12:47
     * @return void
     */
    @Test
    void range() throws Exception {
        //创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫描对象。
        Scanner sc=new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int array[] = new int[n];
        for(int i=0;i<n;i++){
            array[i] = sc.nextInt();
        }
        sc.close();
        System.err.println("控制台输入n:"+n+",k:"+k+",数组数据:"+Arrays.toString(array));
        //默认数组方式
        //int[] array = {1,2,3,4,5};
        //int compute = RangeDemo.compute(5, 2, array);
        int compute = RangeDemo.compute(n, k, array);
        System.err.println("满足条件的集合总数:"+compute);
    }

}

3、运行测试用例

控制台输入:
5 2
1
2
3
4
5

4、测试结果

见证奇迹的时刻

控制台输入n:5,k:2,数组数据:[1, 2, 3, 4, 5]
满足条件的集合:[1,2,3]
满足条件的集合:[1,2,3,4]
满足条件的集合:[2]
满足条件的集合:[2,3,4,5]
满足条件的集合:[3,4,5]
满足条件的集合:[4]
满足条件的集合总数:6

总结

K倍区间这个试题较为简单,题目可以说的比较复杂,其实读明白了就是数组中一个多个连续的元素之和能够被K整除就算作一个子数组,最后返回满足规则中的子数组个数即可。该试题为【蓝桥杯】简单试题,这也告诉我们在做题的时候应该读懂题目意思,能够看起来字数多的题目其实很简单。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小沈同学呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值