1 条题解
-
0
详细题解:A Tale of Two Lands
(数学化简 + 双指针 / 二分,)
一、核心公式化简(最关键部分)
题目要求:
$$\min(|x-y|,\ |x+y|)\ \le\ |x|,|y|\ \le\ \max(|x-y|,\ |x+y|) $$步骤 1:正负号不影响答案
无论 正负,只需要看它们的绝对值。 因为:
- 不变
- 和 只是交换,不影响包含关系
所以我们可以直接把所有数取绝对值。
步骤 2:最终等价条件
设 ,条件化简为:
$$\boldsymbol{x \le 2y \quad \text{且} \quad y \le 2x} $$也就是说: 两个数中,较大的数不能超过较小数的 2 倍。
二、解法流程
- 把数组中所有数取绝对值
- 从小到大排序
- 使用双指针统计满足 的无序数对 数量
三、双指针算法原理
数组已排序:
对每个左端点 :
- 找到最大的 满足
- 那么: 都和 构成合法数对
- 贡献:
总答案 = 所有贡献之和。
四、标程代码(C++)
#include <iostream> #include <vector> #include <algorithm> using namespace std; typedef long long ll; int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector<ll> a(n); for (auto &x : a) { cin >> x; x = abs(x); // 取绝对值 } sort(a.begin(), a.end()); ll ans = 0; int r = 0; for (int l = 0; l < n; l++) { // 找到最远的 r 满足 a[r] <= 2*a[l] while (r < n && a[r] <= 2 * a[l]) r++; ans += r - l - 1; } cout << ans << endl; return 0; }
五、复杂度分析
- 排序:
- 双指针:
- 总复杂度: 可轻松通过 。
六、样例解释
样例 1
输入:
2 5 -3取绝对值:[2,5,3]排序:[2, 3, 5]- : → 贡献
- : → 贡献
- : → 贡献
答案:2
样例 2
输入:
3 6取绝对值:[3,6]排序:[3,6]- : → 贡献
答案:1
七、总结(一句话)
把所有数取绝对值、排序, 双指针统计满足 大数 ≤ 2×小数 的无序数对数量。
- 1
信息
- ID
- 6711
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者