跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

二分算法实战:A-B 数对与高考志愿问题解析

二分查找作为算法竞赛中的高频考点,常应用于统计匹配与最优解寻找。以 A-B 数对与烦恼的高考志愿为例,可深入理解排序预处理、lower_bound 与 upper_bound 的区间统计技巧,以及手动实现二分时的边界细节。针对高考志愿问题,引入哨兵节点优化边界判断能显著提升代码健壮性。结合 C++ STL 与手写二分对比,有助于掌握二段性思想,提升解题效率。

Stephaine Walsh发布于 2026/3/22更新于 2026/5/911 浏览
二分算法实战:A-B 数对与高考志愿问题解析

二分算法实战:A-B 数对与高考志愿问题解析

二分查找是算法竞赛中的高频考点,核心在于利用数据的有序性或二段性快速定位目标。本文将通过 A-B 数对与烦恼的高考志愿两道经典例题,系统讲解从排序预处理到边界处理的完整思路。

A-B 数对

题目描述

给定一个整数数组和一个常数 C,求满足 A - B = C 的数对 (A, B) 的数量。顺序不影响结果。

解题思路

方程可变形为 B = A - C。由于 C 已知,我们可以枚举所有的 A,然后在数组中查找是否存在对应的 B。为了高效统计,先将数组排序。利用二分查找可以快速确定值为 B 的元素区间长度。

这里涉及两个 STL 函数:

  • lower_bound:返回第一个大于等于 k 的位置。
  • upper_bound:返回第一个大于 k 的位置。

两者相减即为值等于 k 的元素个数。注意 ST L 函数要求序列有序,且区间为左闭右开。

代码实现

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
const int N = 2e5 + 10;
LL a[N];

int main() {
    int n, c;
    cin >> n >> c;
    for (int i = 1; i <= n; i++) cin >> a[i];
    
    // 排序是二分的前提
    sort(a + 1, a + 1 + n);
    
    LL ret = 0;
    for (int i = 2; i <= n; i++) {
        LL b = a[i] - c;
        // 在 [1, i] 范围内查找值为 b 的区间
        // lower_bound 找 >= b 的第一个位置
        // upper_bound 找 > b 的第一个位置
        ret += upper_bound(a + 1, a + i + 1, b) - lower_bound(a + 1, a + 1 + i, b);
    }
    cout << ret << endl;
    return 0;
}

提示:STL 二分仅适用于有序序列。若数据无序但具备二段性(如单调性),则需手动实现二分逻辑。

烦恼的高考志愿

题目描述

给定 m 所学校的录取分数线和 n 个学生的成绩,为每个学生找到录取分数与其成绩差值最小的学校,求所有学生最小差值的总和。

解题思路

首先对学校分数线进行排序。对于每个学生的成绩 b,我们需要在分数线中找到最接近的值。使用二分查找找到第一个大于等于 b 的位置 pos。

最优匹配点要么在 pos,要么在 pos - 1。计算这两个位置的差值绝对值,取较小者累加即可。

边界处理细节: 如果所有分数线都大于 b,pos 可能指向首元素,此时 pos - 1 越界;反之亦然。为了避免判断越界,可以在数组两端添加哨兵节点(左右护法),扩大搜索范围并简化逻辑。

代码实现

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

typedef long long LL;
const int N = 1e5 + 10;
const LL INF = 1e7;

LL a[N], b[N];
int m, n;

// 手动实现二分查找,寻找第一个 >= x 的位置
LL find(LL x) {
    int l = 1, r = m;
    while (l < r) {
        LL mid = (l + r) / 2;
        if (a[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return l;
}

int main() {
    cin >> m >> n;
    for (int i = 1; i <= m; i++) cin >> a[i];
    
    // 设置哨兵,防止边界越界
    a[0] = -INF;
    sort(a + 1, a + 1 + m);
    
    LL ret = 0;
    for (int i = 1; i <= n; i++) {
        cin >> b[i];
        LL pos = find(b[i]);
        // 比较 pos 和 pos-1 两个位置的距离
        ret += min(abs(a[pos] - b[i]), abs(a[pos - 1] - b[i]));
    }
    cout << ret << endl;
    return 0;
}

总结

二分查找的本质是寻找'二段性'。无论是利用 STL 库函数还是手写实现,关键在于理解单调性与边界条件。掌握这两道典型题目后,面对类似的区间统计或最值逼近问题,便能迅速构建出高效的解决方案。

目录

  1. 二分算法实战:A-B 数对与高考志愿问题解析
  2. A-B 数对
  3. 题目描述
  4. 解题思路
  5. 代码实现
  6. 烦恼的高考志愿
  7. 题目描述
  8. 解题思路
  9. 代码实现
  10. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 堆的 Shift Down 操作详解:从最大堆中取出元素
  • JavaScript 基础:WebGL 常量、命名规范与绘图初始化
  • OpenClaw 多 AI 集成全渠道电商自动化架构
  • 不写代码创建 Agent:尝试字节跳动 Coze 平台
  • LazyLLM 多 Agent 应用实践:源码部署与 Web 调试指南
  • AIGC 时代的医学统计学:Python 数据分析实战
  • Winboat 在 Linux 桌面运行 Windows 应用指南
  • HashMap、ArrayMap 与 SparseArray 对比及选型指南
  • 扩散模型原理与基于 DDPM 的图像生成实战
  • 降低 AIGC 检测率的提示词优化策略与实践指南
  • 嵌入式转 FPGA 学习路径与职业建议
  • AI 大模型开发转行指南:学习路径与求职建议
  • Transformer 模型核心原理与从零实现详解
  • Hugging Face Transformers 大模型开发实战指南
  • 大模型时代:新手与程序员如何转型入局
  • Git 从零基础到大神:安装、操作、分支与协作指南
  • 纯前端 JavaScript 通过 IP 地址获取用户地理位置
  • 知网AIGC检测怎么过?2026最新降AI率全流程攻略
  • openJiuwen 企业级 Agent 平台深度解析:从架构设计到实战部署
  • Stable Diffusion WebUI 无障碍改造:键盘导航与屏幕阅读器适配

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online