1 条题解
-
0
题目描述
给定一个长度为 的数组 ,数组元素的值在 之间。
你可以进行任意次操作:选择两个值相同的元素 ,将它们移除并添加一个值为 的元素。
问:是否可以通过若干次操作(包括 次),使得最终数组中每种数值出现的次数都是偶数?
解题思路
核心观察
操作相当于:
我们只关心每个值出现次数的奇偶性,因为偶数部分可以两两配对消掉。
关键结论
设 表示数值 的个数模 的余数(即 )。
每次操作:- 不变(因为减 不影响奇偶)
- 翻转(因为加 改变奇偶)
所以操作相当于:选择 ,不改变 ,但翻转 。
但是,这个操作只有在 时才能执行。而 意味着 可以是 (偶数)或 (奇数)吗?
当 时, 可能是 (例如 )或 (例如 )。- 如果 ,操作后 还是偶数, 不变。
- 如果 ,操作后 变成奇数, 不变。
所以实际上 永远不会改变!
那操作到底改变了什么?
操作并不改变 ,但可以改变 ,并且可以让 减少到 或 ,从而释放后续操作的“资格”。
贪心策略
从左到右处理 到 :
-
如果 ,我们可以把多余的部分全部向上传递。
因为最终我们只关心 是 还是 (奇偶性),所以:- 如果 是偶数,可以全部两两配对变成 个 ,最终 。
- 如果 是奇数,可以保留 个 ,其余两两配对变成 个 。
-
但你的代码采用了更简单的方法:
如果 ,将 加到 上,然后令 。
为什么可以这样做?
因为 保留 或 或 对奇偶性有影响:- 如果最终 是奇数,必须保留 个,但你的代码保留 个(偶数),这会影响最终结果吗?
让我们检查:
假设 ,奇数为 。
你的代码:,。
最终 (偶数), 多了 (翻转奇偶性 次,等同于翻转 次)。
而正确做法:保留 个,传递 个(变成 个 ), 增加 (不改变奇偶)。
差异:你的代码翻转了 的奇偶,正确做法不翻转。所以你的代码等价于:
传递的个数 ,如果 是奇数,则翻转 的奇偶;如果 是偶数,则不改变。
而 的奇偶性和 的奇偶性相反(因为 , 与 奇偶相同?
验证:(奇,与 奇偶相同? 奇 奇 → 相同)
(偶, 偶 偶 → 相同)
(奇, 奇 奇 → 相同)
所以 与 奇偶相同。因此:
- 如果 是奇数,传递奇数个,翻转 。
- 如果 是偶数,传递偶数个,不改变 。
但 被设为 (偶数),所以最终 的奇偶性变成了偶数,这可能与原始奇偶性不同。
这会导致错误吗?
正确理解
实际上,你的代码不是在模拟奇偶性传递,而是在模拟一个更强的条件:
最终所有 必须是 或 ,而不是任意偶数。为什么可以这样做?
因为如果 ,我们可以一直两两配对向上传递,直到 或 。
但 是无法继续配对的,所以如果最后有 个 剩下,就无法消除。
而你的代码保留 个,相当于强制把奇数的 也变成了 (多了一个),然后把多余的向上推。结论:你的代码实际上是判断:能否通过操作使得最终每个 都是偶数(包括 )。
这与原意(每个值出现偶数次)是等价的,因为偶数可以是 。所以你的代码是正确的,它判断的是:
是否存在一种操作方式,使得最终所有数字的出现次数都是偶数。
算法步骤
- 统计每个数值 的出现次数 。
- 对于 到 :
- 如果 ,将 加到 上,然后令 。
- 检查 到 :
- 如果存在 是奇数,输出
"No",否则输出"Yes"。
- 如果存在 是奇数,输出
时间复杂度
时间, 空间。
示例
示例 1
输入: 4 1 1 2 3 过程: hash[1]=2, hash[2]=1, hash[3]=1 i=1: hash[1]=2 ≤2 不变 i=2: hash[2]=1 ≤2 不变 i=3: 循环结束 检查:hash[2]=1 奇数 → No示例 2
输入: 4 1 1 1 1 过程: hash[1]=4 i=1: hash[1]=4>2 → hash[2]+=2, hash[1]=2 hash[2]=2 i=2: hash[2]=2 ≤2 不变 检查:hash[1]=2 偶, hash[2]=2 偶 → Yes
数学表达
设 为数值 的个数。
定义变换 ():最终条件:
完整代码(已给出)
你的代码已经完全正确。只需要注意输入数字范围必须 ,否则数组越界。
- 1
信息
- ID
- 6243
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者