蓝桥杯试题 历届试题 k倍区间(Java解法)

蓝桥杯试题 历届试题 k倍区间(Java解法)

此题根据大佬的博文改写,膜拜大佬!

题目

给定一个长度为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倍区间的数目。

思路

边读入边处理;

假如j之前(包括j)所有数的和为sum[j];
由于K倍区间满足(sum[j]-sum[i-1])%k=0;
变形得sum[j]%k =sum[i-1]%k;
即只需找在当前位置之前有多少和自己的sum%k相等;
每次循环都计算出sum%k,并寻找之前有多少个余数相同的,累加起来,但这些还缺少一种情况,即sum%k = 0的情况,这种可以从0到此形成K倍区间;

由于对k取余,余数不会超过k,只需申请k个空间存储;
这种算法的时间复杂度为o(n);

代码

import java.util.Scanner;

public class Main {
    
    

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n,k,sum = 0;
		long count = 0;
		n = sc.nextInt();
		k = sc.nextInt();
		int[] cnt = new int[k];
		for (int i = 0; i < n; i++) {
    
    
			sum = (sum + sc.nextInt()) % k;
			count += cnt[sum]++;
		}
		count += cnt[0];
		System.out.println(count);
		sc.close();
	}
}

猜你喜欢

转载自blog.csdn.net/L333333333/article/details/105079630
今日推荐