1 条题解
-
0
题目大意
给定一个长度为 的序列 ,它是由原序列 删除 个元素后得到的。已知原序列 所有元素的乘积为 。要求判断这样的序列 是否存在,若存在则输出任意一组被删除的 个数。
解题思路
设序列 中所有元素的乘积为 ,即
由于 的乘积为 ,而 由 中的元素与被删除的 个元素共同组成,因此被删除的 个元素的乘积必然等于
由此可以得到以下判定条件:
- 若 不能被 整除(即 ),则不可能找到整数乘积为 的被删除元素,此时答案必为
NO。 - 若 能被 整除,则一定存在合法的构造方案。一种最简单的构造是:将 作为被删除的第一个数,其余 个数全部补 。由于 不影响乘积,且 为正整数,因此该构造一定合法。
注意:题目并未要求被删除的数必须为 的因数,只要乘积满足条件即可。上述构造中, 以及 都是合法的整数。
算法步骤
- 读入测试用例数 。
- 对每个测试用例:
- 读入 以及序列 。
- 计算 中所有元素的乘积 (注意使用
long long类型防止溢出,虽然 ,乘积最大为 ,仍在 位整数范围内)。 - 判断 是否能被 整除:
- 若不能,输出
NO。 - 若能,输出
YES,然后先输出 ,再输出 个 (若 则不输出数字)。
- 若不能,输出
复杂度分析
- 时间复杂度:每个测试用例 计算乘积,总复杂度 ,在 的范围内完全可行。
- 空间复杂度: 额外空间。
代码实现(C++)
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int n, k; cin >> n >> k; long long x = 1; for (int i = 0; i < n; ++i) { int b; cin >> b; x *= b; } if (2023 % x != 0) { cout << "NO\n"; } else { cout << "YES\n"; cout << 2023 / x; for (int i = 1; i < k; ++i) { cout << " 1"; } cout << "\n"; } } return 0; }
补充说明
- 题目中的 不一定为 的因数,但这不影响判定。因为只要最终乘积能整除,我们就可以通过补 和调整一个乘数来达到目标。
- 由于 ,其质因数分解唯一,因此判定条件的正确性由整数除法的性质保证。
- 若 不能被 整除(即 ),则不可能找到整数乘积为 的被删除元素,此时答案必为
- 1
信息
- ID
- 6492
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 1
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者