题解:学而思编程 调整元素
【题目来源】
学而思编程:调整元素
【题目描述】
给定 \(n\) 个整数元素 \(a_1,a_2,…,a_n\)。可以进行无限次操作,每次操作可以使其中任意一个元素的值增加 \(2\)。
请问,是否可以通过若干次操作使得所有元素的值都相等。
【输入】
第一行包含整数 \(T\),表示共有 \(T\) 组测试数据。
每组数据:
第一行包含整数 \(n\)。
第二行包含 \(n\) 个整数 \(a_1,a_2,…,a_n\)。
【输出】
每组数据输出一行结果,能使得数组中所有元素的值都相等则输出 Yes,否则输出 No。
【输入样例】
3
2
1 3
3
2 4 6
4
1 3 4 7
【输出样例】
Yes
Yes
No
【核心思想】
-
问题分析:给定 \(n\) 个整数 \(a_1, a_2, \ldots, a_n\),每次操作可将任意元素增加 \(2\)。判断是否能使所有元素相等。这是一个不变量分析问题,关键在于发现操作对元素奇偶性的影响规律。
-
算法选择:
- 奇偶不变性(Parity Invariant):分析操作 \(x \rightarrow x + 2\) 对元素奇偶性的影响
- 分类统计:统计数组中奇数和偶数的个数,根据不变量判定可行性
-
关键步骤:
- 读取输入:读取测试用例数量 \(T\)
- 逐组处理(循环 \(T\) 次):
- 读取数组长度 \(n\)
- 统计奇偶性:初始化 \(odd = 0\),\(even = 0\),遍历 \(n\) 个元素:
- 若 \(a_i \bmod 2 = 0\),则 \(even \leftarrow even + 1\)
- 否则 \(odd \leftarrow odd + 1\)
- 判定条件:若 \(odd = 0\)(全为偶数)或 \(even = 0\)(全为奇数),输出
Yes;否则输出No
-
时间/空间复杂度:
- 时间复杂度:\(O(T \times n)\),每组数据需遍历 \(n\) 个元素进行奇偶统计
- 空间复杂度:\(O(1)\),仅使用 \(odd\)、\(even\) 两个计数器,无需存储整个数组
-
奇偶不变性的核心思想:
- 操作保奇偶性:对任意整数 \(x\),\(x + 2\) 与 \(x\) 的奇偶性相同,即 \((x + 2) \bmod 2 = x \bmod 2\)。因此增加 \(2\) 的操作不会改变元素的奇偶性
- 等价类划分:所有整数按奇偶性分为两个等价类——奇数类和偶数类。操作只能在同一类内部移动,无法跨类转换
- 目标可达条件:要使所有元素相等,它们必须属于同一奇偶类。若数组中同时存在奇数和偶数,则无论如何操作,奇数永远是奇数,偶数永远是偶数,不可能全部相等
- 充分性证明:若所有元素同奇偶,设最大值为 \(max\),由于每次可加 \(2\),任何元素 \(a_i\) 都可以通过 \((max - a_i)/2\) 次操作达到 \(max\)(同奇偶保证差值为偶数,可被 \(2\) 整除)
- 适用于分析操作对模某数余数的影响、判定状态可达性的不变量类问题
【算法标签】
数学
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int t; // 测试用例数量
int main()
{
cin >> t; // 输入测试用例数量
while (t--) // 处理每个测试用例
{
int n; // 数组中元素个数
cin >> n; // 输入数组大小
int x; // 临时变量,用于读取每个元素
int odd = 0; // 奇数计数器
int even = 0; // 偶数计数器
// 读取数组元素并统计奇偶性
for (int i = 1; i <= n; i++)
{
cin >> x; // 输入一个数字
if (x % 2 == 0) // 如果是偶数
{
even++; // 偶数计数加1
}
else // 如果是奇数
{
odd++; // 奇数计数加1
}
}
// 判断条件:如果只有奇数或只有偶数
if (odd == 0 || even == 0) // 如果全部是偶数或全部是奇数
{
cout << "Yes" << endl; // 输出Yes
}
else
{
cout << "No" << endl; // 输出No
}
}
return 0; // 程序正常结束
}
【运行结果】
3
2
1 3
Yes
3
2 4 6
Yes
4
1 3 4 7
No
浙公网安备 33010602011771号