2017年第八届蓝桥杯—— k倍区间
题目描述
资源限制
时间限制:2.0s 内存限制:256.0MB
问题描述
给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
你能求出数列中总共有多少个K倍区间吗?
输入格式
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
输出格式
输出一个整数,代表K倍区间的数目。
样例输入
5 2
1
2
3
4
5
1
2
3
4
5
样例输出
6
数据规模和约定
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
解题思路——前缀和+hash
具体思路见LeetCode每日一题——523. 连续的子数组和(同余定理)
AC代码
1 import java.util.*; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner input = new Scanner(System.in); 6 int N = input.nextInt(); 7 int K = input.nextInt(); 8 Map<Long, List<Integer>> map = new HashMap<>(); 9 List<Integer> temp = new ArrayList<>(); 10 temp.add(-1); 11 map.put(0L, temp); 12 long prefix = 0; 13 long res = 0; 14 15 for (int i = 0; i < N; i++) { 16 int a = input.nextInt(); 17 prefix += a; 18 prefix %= K; 19 if (map.containsKey(prefix)) { 20 List<Integer> t = map.get(prefix); 21 res += t.size(); 22 t.add(i); 23 } else { 24 List<Integer> t = new ArrayList<>(); 25 t.add(i); 26 map.put(prefix, t); 27 } 28 } 29 System.out.println(res); 30 } 31 } 32 33 class MyArea { 34 int left; 35 int right; 36 37 public MyArea(int left, int right) { 38 this.left = left; 39 this.right = right; 40 } 41 42 @Override 43 public boolean equals(Object o) { 44 if (this == o) return true; 45 if (o == null || getClass() != o.getClass()) return false; 46 MyArea myArea = (MyArea) o; 47 return left == myArea.left && right == myArea.right; 48 } 49 50 @Override 51 public int hashCode() { 52 return Objects.hash(left, right); 53 } 54 }