abc233_c Product 题解
Product
题意
有 \(n\) 个集合,第 \(i\) 个集合中有 \(l_i\) 个数,分别为 \(a_{i,1}, a_{i,2} \ldots a_{i,l_i}\)
从每个集合中选取一个数,问:有多少种取法使得取出的数的乘积为 \(x\)。
数据范围
- \(n,l_i \geqslant 2\)
- \(\prod\limits_{i=1}^{n}l_i \leqslant 10^5\)
- \(1 \leqslant a_{i,j} \leqslant 10^9, 1 \leqslant x \leqslant 10^{18}\)
思路
这题其实很easy,只需要爆搜就可以AC了。
可以分析出 \(n\) 是不超过 \(20\) 的,因为 \(l_i\) 至少为 \(2\) 且乘积不超过 \(10^5\),所以 \(n=\log_{2} \prod_{i=1}^{n}l_i\)。
由于题目给的数据范围限制了 \(l_i\) 的乘积是不超过 \(10^5\) 的,所以可以A掉。
复杂度
时间:\(O(\prod\limits_{i=1}^{n}l_i)\)
空间:\(O(n \times \prod\limits_{i=1}^{n}l_i)\)
Code
点击查看代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
using ll = long long;
const int L = 1e5 + 10;
int n, ans, l[20], a[20][L];
ll x;
void dfs (int t, ll y) {
if (y > x || y < 1) {
return ;
}
if (t == n + 1) {
if (y == x) {
ans++;
}
return ;
}
for (int i = 1; i <= l[t]; i++) {
dfs(t + 1, y * a[t][i]);
}
}
int main(){
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> x;
for (int i = 1; i <= n; i++) {
cin >> l[i];
for (int j = 1; j <= l[i]; j++) {
cin >> a[i][j];
}
}
dfs(1, 1);
cout << ans;
return 0;
}