1 条题解
-
0
题目回顾(原题:Tender Carpenter)
给定一个数组 。
一个整数集合 是稳定的,当且仅当:从 中任意选取三个数 (可以重复)作为边长,都能构成一个非退化三角形。非退化三角形的条件是:
要求将数组划分成若干个连续非空子段,使得每个子段内所有元素构成的集合都是稳定的。
问:是否存在至少两种不同的划分方式?
核心数学结论
引理 1:稳定集合的等价条件
一个集合 是稳定的 当且仅当 以下条件成立:
证明:
-
必要性:如果 ,取 ,,,则 ,不满足三角不等式,矛盾。
-
充分性:如果 ,则对任意 ,有:
同理可证其他两个不等式,因此三角不等式全部成立。
转化为数组划分问题
对于一个连续子段 ,设:
该子段稳定 。
最少划分方式分析
基础划分
划分一:每个元素单独成段。
- 单元素集合 显然稳定(因为只能选三个相同的数 ,满足 )。
因此,至少存在一种划分方式(每个元素单独成段)。
寻找第二种划分
如果存在另一种不同的划分方式,则必须满足:存在某个长度 的子段是稳定的,并且剩余部分也能划分成稳定段。
关键定理
定理:存在至少两种不同划分方式 当且仅当 存在至少一个 ()使得:
证明:
充分性:若存在这样的 ,则:
- 划分一:
- 划分二:将 和 合并成一个子段 ,其余元素单独成段
由于 ,该子段稳定。划分二与划分一不同(长度少 )。因此至少存在两种划分。
必要性:若不存在这样的 ,即对所有 ,都有:
则任何长度 的连续子段都不稳定(因为取该子段的最小值和最大值一定出现在某对相邻元素中,而该对相邻元素不满足稳定条件)。因此,唯一可行的划分是每个元素单独成段,划分方式唯一。
算法步骤
- 读入测试用例个数
- 对于每个测试用例:
- 读入 和数组
- 遍历 到 :
- 如果 ,则标记为存在
- 如果存在,输出
"YES",否则输出"NO"
时间复杂度
- 每个测试用例
- 总时间复杂度
完整题解代码
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } bool ok = false; for (int i = 0; i < n - 1; i++) { if (2 * min(a[i], a[i + 1]) > max(a[i], a[i + 1])) { ok = true; break; } } cout << (ok ? "YES" : "NO") << "\n"; } return 0; }
验证样例
输入 相邻对检查 结果 ✅ YES 无满足条件 NO ✅ YES ✅ 与题目样例输出完全一致。
总结
关键点 结论 稳定性条件 至少两种划分的条件 存在相邻元素对满足上述条件 时间复杂度 空间复杂度 -
- 1
信息
- ID
- 6466
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者