跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

二分算法实战:A-B 数对与烦恼的高考志愿

二分算法在 A-B 数对统计与高考志愿匹配中的应用。通过排序预处理,利用 lower_bound 和 upper_bound 快速定位区间长度或最优解。重点讲解边界处理、STL 函数使用及手动实现二分的细节,解决无序数组查询与二段性问题。

RefactorPro发布于 2026/3/29更新于 2026/6/318 浏览
二分算法实战:A-B 数对与烦恼的高考志愿

简介

本文将通过两道经典二分查找例题 ——A-B 数对与烦恼的高考志愿,系统讲解二分查找的核心思想与实用技巧。涵盖排序预处理、lower_bound、upper_bound 的灵活运用,以及手动实现二分与边界细节处理。

一、A-B 数对

1.1 题目

链接:A-B 数对

1.2 算法原理

由于顺序不影响最终结果,所以可以先把整个数组排序,来研究是否有其他的性质。 由 A − B = C 得:B = A − C,由于 C 是已知的数,我们可以从前往后枚举所有的 A,然后去前面找有多少个符合要求的 B,正好可以用二分快速查找出区间的长度。

【STL 使用】

  1. lower_bound:传入要查询区间的左右迭代器(注意是左闭右开的区间,如果是数组就是左右指针)以及要查询的值 k,然后返回该数组中 >= k 的第一个位置。
  2. upper_bound:传入要查询区间的左右迭代器(注意是左闭右开的区间,如果是数组就是左右指针)以及要查询的值 k,然后返回该数组中 > k 的第一个位置;

例:a = [10, 20, 20, 20, 30, 40],设下标从 1 开始计数,在整个数组中查询 20:lower_bound(a + 1, a + 1 + 6, 20),返回 a + 2 位置的指针;upper_bound(a + 1, a + 1 + 6, 20),返回 a + 5 位置的指针; 然后两个指针相减,就是包含 20 这个数区间的长度。

1.3 代码

#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; ret +=upper_bound(a +1,a + i +1,b)-lower_bound(a , a + i, b);}
 cout << ret << endl;
 return0;}
+1
+1

注:同时 STL 的使用范围很「局限」,查询「有序序列」的时候才有用,数组无序的时候就无法使用。但是我们的二分算法也能在「数组无序」的时候使用,只要有「二段性」即可。

二、烦恼的高考志愿

2.1 题目

链接:烦恼的高考志愿

2.2 算法原理

先把学校的录取分数「排序」,然后针对每一个学生成绩,在「录取分数」中二分出≥ b 的「第一个」位置 pos,那么差值最小的结果要么在 pos 位置,要么在位置 pos - 1,那么最后的不满意度求法就为:abs(a[pos] − b) 与 abs(a[pos − 1] − b) 的最小值。

注:细节问题 如果所有元素都大于 b 的时候,pos − 1 会在 0 下标的位置,有可能结果出错; • 如果所有元素都小于 pos 的时候,pos 会在 n 的位置,此时结果倒不会出错,但是我们要想到这个细节问题,这道题不出错不代表下一道题不出错。 解决方法:加上两个左右护法,结果就不会出错了。

2.3 代码

//烦恼的高考志愿
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL a[N],b[N],m,n;
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]=-1e7;
 sort(a +1, a +1+ m);
 LL ret =0;
 for(int i =1; i <= n; i++){
  cin >> b[i];
  LL pos =find(b[i]);
  ret +=min(abs(a[pos -1]- b[i]),abs(a[pos]- b[i]));}
 cout << ret << endl;
 return0;}

目录

  1. 简介
  2. 一、A-B 数对
  3. 1.1 题目
  4. 1.2 算法原理
  5. 1.3 代码
  6. 二、烦恼的高考志愿
  7. 2.1 题目
  8. 2.2 算法原理
  9. 2.3 代码
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • Java RESTful 接口开发:核心详解与最佳实践
  • 基于 Rokid 灵珠平台构建旅游 AR 智能体
  • Linux 信号内核结构、保存与处理全链路剖析
  • Mac mini 部署 OpenClaw:接入国产大模型与飞书机器人
  • 大模型技术从入门到实战指南
  • AI 变现核心逻辑:为何学完百种工具仍难盈利
  • 链式二叉树详解:递归遍历与核心接口实现
  • Python Flask 校园拍卖系统设计与实现
  • 基于 aivectormemory 实现 AI 长期记忆方案
  • 论文查重与 AIGC 检测技术解析:从痛点到解决方案
  • SpringBoot+Vue+Netty+WebSocket+WebRTC 实现视频聊天
  • Web 项目 UI 自动化测试实战:从零搭建博客系统框架
  • Python 官方文档查阅与打包技术指南
  • 通义千问 7B 本地部署实战方案
  • 国内可用免费 AI 工具与学习资源整理
  • IntelliJ IDEA 中修改 Git 提交用户名的方法
  • 基于 FPGA 的北斗导航自适应抗干扰算法设计与实现
  • Linux 下 OpenClaw 快速安装、初始化与 Web UI 配置指南
  • 算法模型训练全流程解析:从决策边界到模型部署
  • GitHub 多模态大模型项目复现流程

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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