题目描述
游游拿到了一个数组,她准备在其中选择两个数,使得乘积的末尾至少有x个0。游游想知道,至少有多少种不同的取数方法?
输入描述:第一行输入两个正整数n和x,代表数组的大小以及乘积末尾0的数量。第二行输入n个正整数ai,代表游游拿到的数组。1≤n,x≤10^5,1≤ai≤10^9
输出描述:输出一个整数,代表游游选择的方案数。
#include <iostream>
#include <vector>
using namespace std;
const int MAX_R = 40, MAX_C =20;
int main() {
vector<vector<int>> cnt(MAX_R, vector<int>(MAX_C));
int n, x;
cin >> n >> x;
for (int i = 0; i < n; ++i) {
int ai;
cin >> ai;
int p2 = 0, p5 = 0;
while (ai % 2 == 0) {
p2++, ai /= 2;
}
while (ai % 5 == 0) {
p5++, ai /= 5;
}
cnt[p2][p5]++;
}
long long ans = 0;
for (int i = 0; i < MAX_R; ++i) {
for (int j = 0; j < MAX_C; ++j) {
for (int i2 = max(0, x - i); i2 < MAX_R; ++i2) {
for (int j2 = max(0, x - j); j2 < MAX_C; ++j2) {
ans += (i == i2 && j == j2 ? cnt[i][j] * (cnt[i][j] - 1LL) : cnt[i][j] * cnt[i2][j2]);
}
}
}
}
cout << ans / 2 << endl;
return 0;
}
有一个由整数构成的序列,每个整数ai
都可以分解成2的幂和5的幂的乘积,比如ai = 2^p2 * 5^p5
。程序首先统计序列中整数ai
分解后,2的幂次方(p2
)和5的幂次方(p5
)的各种组合出现的次数,存储在一个二维矩阵cnt
中,矩阵的行表示2的幂次方,列表示5的幂次方。
接着,程序试图计算满足特定条件的元素对的数量,并将结果除以2。条件可能是两个整数ai
和aj
满足|p2(i) - p2(j)| <= x
且|p5(i) - p5(j)| <= x
,其中p2(i)
和p5(i)
分别表示整数ai
分解后2的幂次方和5的幂次方。
为了达到这一目的,代码使用了四个嵌套循环来遍历cnt
矩阵中的所有可能的(i, j)
和(i2, j2)
组合,计算满足条件的元素对数量,并累加到ans
变量中。最后,由于计算的是元素对,所以在输出结果之前将ans
除以2,避免重复计数。需要注意的是,这里的x
是从输入中读取的参数,它代表了允许的最大幂次差值。