1 条题解
-
0
题目题解
问题理解
给定数组 ,可以删除任意元素(保持相对顺序),问能否得到非空乱序数组 。
乱序定义:将 排序后得到 ,要求 对所有 成立。
第一步:何时一定无解?
如果原数组 本身已经是非递减的,那么无论如何删除元素,剩余数组仍然是非递减的。
因为删除操作不改变相对顺序,若原数组已经有序,任何子序列也是有序的。
此时,剩余数组排序后就是它自身,必然有 ,不可能成为乱序数组。因此,若 非递减,则答案为
"NO"。
第二步:何时一定有解?
若原数组不是非递减的,则存在一对下标 使得 。
我们只需保留这两个元素,删除其余所有元素,得到数组 。- 该数组长度为 ,排序后为 。
- 由于 ,显然 且 ,因此满足乱序条件。
所以,只要存在逆序对,就可以构造长度为 的乱序数组。
第三步:构造方法
- 遍历所有 ,找到第一个 的位置。
- 输出
"YES",然后输出 和 。 - 如果不存在这样的对,输出
"NO"。
时间复杂度
- 最坏情况需检查所有 对,但 ,完全可行。
- 总复杂度 ,满足要求。
代码实现
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (a[i] > a[j]) { cout << "YES\n"; cout << "2\n"; cout << a[i] << " " << a[j] << "\n"; return; } } } cout << "NO\n"; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { solve(); } return 0; }
验证样例
测试用例 数组 是否存在逆序对 输出 1 否(非递减) "NO"2 是() "YES\n2\n5 2"或"4 5 2 4"3 否(单元素) "NO"与题目输出一致(注意第二组有多种构造,输出
5 2也是正确的)。
总结
本题的关键在于:
- 非递减数组永远无法成为乱序数组。
- 只要存在一个逆序对,就可以只保留这两个元素构成乱序数组。
- 因此答案仅取决于原数组是否严格非递减。
- 1
信息
- ID
- 6245
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 1
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者