1 条题解
-
0
A. 樱子的考试 - 详细题解
问题重述
给定 个 和 个 ,在每个数前添加正号或负号,问能否使整个数组的和为 。
问题转化
在每个数前添加 或 ,相当于将数组分成两个子集:
- 带正号的数放入集合
- 带负号的数放入集合
数组总和为 等价于:
而所有数的总和为:
$$S = \sum_{x \in P} x + \sum_{x \in N} x = 2 \times \sum_{x \in P} x $$因此,总和 必须是偶数,且每个子集的和为 。
必要条件分析
设 个 , 个 ,则总和为:
条件 1:总和为偶数
所以 为偶数当且仅当 为偶数。
结论:若 是奇数,则直接输出
"NO"。
条件 2:能否凑出
当 为偶数时,设 ,则:
$$\frac{S}{2} = \frac{a + 2b}{2} = \frac{2k + 2b}{2} = k + b $$我们需要判断能否用若干 和 凑出 。
关键观察:
- 每个 可以看作两个 的替代
- 我们实际上是在分配符号,等价于选择一部分数放在正号集合
分类讨论
情况 1: 为偶数
当 为偶数时,可以将 平均分成两组,每组 个 ,和为 。
再加上 个 到正号集合,就能得到 。结论: 为偶数时,答案为
"YES"。
情况 2: 为奇数
当 为奇数时,无法将 完全平分。
设 ,则 。将 尽量平分:每组 个 ,和为 ,还剩下一个 需要分配。
这个剩下的 必须放在正号集合,此时正号集合的和为 ,还需要 个 来凑成 。
因此,需要至少 个 (因为 才能有 ,而 ,所以 )。
更简单的理解:
- 为奇数时,总和为 是奇数?不对, 已经保证为偶数,所以总和是偶数
- 但奇数个 意味着无法直接平分 ,需要用 来平衡
- 若 ,则没有 可以调整,答案为
"NO" - 若 (即至少有两个 ),则可以用两个 (和为 )替代一个 ,实现平衡
结论: 为奇数时
- 若 ,答案为
"NO" - 若 ,答案为
"YES"
算法步骤
- 读入 ( 的个数)和 ( 的个数)
- 若 为奇数,输出
"NO" - 否则( 为偶数):
- 若 为偶数,输出
"YES" - 若 为奇数:
- 若 ,输出
"NO" - 否则输出
"YES"
- 若 ,输出
- 若 为偶数,输出
完整代码
#include <bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while (t--) { int cnt1, cnt2; cin >> cnt1 >> cnt2; if (cnt1 % 2 == 1) { cout << "NO" << endl; } else { if (cnt2 % 2 == 0) { cout << "YES" << endl; } else { if (cnt1 == 0) { cout << "NO" << endl; } else { cout << "YES" << endl; } } } } return 0; }
时间复杂度
- 每个测试用例
- 总复杂度
示例验证
奇偶 奇偶 条件 输出 0 1 偶 奇且 NO 3 2 0 偶 YES 3 奇且 3 1 奇 - NO 与样例输出完全一致。
- 1
信息
- ID
- 6325
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者