1 条题解
-
0
一、核心结论(关键突破口)
先直接给出本题最核心的数学结论,这是标程的灵魂:
一个集合 是稳定集合的充要条件:集合中任意两个元素 ,都满足 。
同时延伸出两个必用结论:
- 若数组中存在任意一对相邻元素 满足 ,答案为 ;
- 若所有相邻元素都不满足这个条件,答案为 。
二、严谨证明(为什么标程是对的?)
1. 稳定集合的定义回顾
集合 稳定 对任意 , 能构成非退化三角形,即:
2. 简化条件:只需检查两个元素
对一个集合,我们只需要保证最大的数 < 另外两个数的和,三角形条件就全部满足(小数字相加一定更大)。
要让任意三个数都满足三角形条件,最严苛的情况是:取集合中最大的数 ,再取两个最小的数 。 此时必须满足:
也就是:
这个条件等价于:集合中任意两个元素,小的那个的2倍 > 大的那个。 即对任意 :
3. 划分方式的意义
- 如果存在一对相邻元素满足条件:我们至少有两种划分:
- 把这两个元素合并成一个子段;
- 把这两个元素分开成两个子段。 因此答案一定是 。
- 如果所有相邻元素都不满足条件:每个元素必须单独作为一个子段,只有唯一一种划分,答案是 。
三、标程代码逐行解析
#include <bits/stdc++.h> #define MAXN 1001 int a[MAXN]; void solve() { int n; std::cin >> n; // 输入数组长度 n for (int i = 1; i <= n; ++i) std::cin >> a[i]; // 输入数组 a[1]~a[n] // 核心逻辑:遍历所有相邻元素对 for (int i = 1; i < n; ++i) // 检查 2*min(a[i],a[i+1]) > max(a[i],a[i+1]) if (2 * std::min(a[i], a[i + 1]) > std::max(a[i], a[i + 1])) { std::cout << "YES\n"; return; // 找到一对就直接输出 YES } // 所有相邻对都不满足,输出 NO std::cout << "NO\n"; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr), std::cout.tie(nullptr); int t; std::cin >> t; while (t--) solve(); // 处理 t 组测试用例 return 0; }核心代码逻辑(仅一行判断)
if (2 * min(a[i], a[i+1]) > max(a[i], a[i+1]))- 满足 可以至少两种划分
- 全部不满足 只有一种划分
四、结合样例验证
样例输入 1
2 100000 100000判断: 满足条件 。
样例输入 2
4 115 9 2 28相邻对:
- :
- :
- :
全部不满足 。
五、算法复杂度
- 时间复杂度: 每组用例,遍历一次数组即可。
- 空间复杂度:,存储数组。
- 完全适配题目数据范围:。
总结
- 核心条件:只要存在一对相邻元素满足 ,答案就是 ;
- 唯一例外:所有相邻元素都不满足该条件,答案为 ;
- 标程本质:线性扫描数组,检查相邻元素对,效率最优、代码极简。
- 1
信息
- ID
- 6465
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者