给出一个长度为 n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n(1≤n≤2⋅10 5 ) 的序列 a a ( 1 ≤ a i ≤ 1 0 9 ) (1≤a i ≤10 9 ),并且保证序列 a a 所有元素乘积 ≤ 1 0 18 ≤10 18 ,求这个序列中满足如下条件的连续子段 [ a l … a r ] [a l …a r ] 的数量: 令 x = a l ⋅ a l + 1 ⋅ a l + 2 … a r x=a l ⋅a l+1 ⋅a l+2 …a r ,那么 x x 的末尾恰好有 k ( 0 ≤ k ≤ 1 0 9 ) k(0≤k≤10 9 ) 个零。 输入描述: 第一行包含一个整数 T ( 1 ≤ T ≤ 1 0 5 ) T(1≤T≤10 5 ),表示测试用例的组数。 对于每组测试用例: 第一行包含两个整数 n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n(1≤n≤2⋅10 5 ) 和 k ( 0 ≤ k ≤ 1 0 9 ) k(0≤k≤10 9 ),表示序列的长度和题目中提到的后导零的数量; 第二行包含 n n 个整数 a 1 … a n ( 1 ≤ a i ≤ 1 0 9 ) a 1 …a n (1≤a i ≤10 9 ),表示该序列。 保证对于所有的测试用例, n n 的总和不超过 2 ⋅ 1 0 5 2⋅10 5 。 输出描述: 对于每组测试用例: 仅输出一行,包含一个整数,表示答案。求java代码
时间: 2023-12-30 18:05:51 浏览: 139
前面已经给出了解题思路和伪代码,下面是完整的 Java 代码实现:
```java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while (T-- > 0) {
int n = sc.nextInt();
int k = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int l = 0, r = 0, cnt = 0;
long prod = 1;
int ans = 0;
while (r < n) {
// 更新 prod 和 cnt
prod *= a[r];
while (prod % 10 == 0) {
prod /= 10;
cnt++;
}
// 如果 cnt 大于 k,需要将 l 向右移动一位
while (cnt > k) {
prod /= a[l];
if (prod % 10 == 0) {
prod /= 10;
cnt--;
}
l++;
}
// 如果 cnt 等于 k,当前窗口满足条件,统计答案
if (cnt == k) {
ans++;
}
r++;
}
System.out.println(ans);
}
sc.close();
}
}
```
阅读全文