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;
}

posted @ 2023-03-01 16:14  wnsyou  阅读(40)  评论(0编辑  收藏  举报