csp信奥赛C++标准模板库STL案例应用3

csp信奥赛C++标准模板库STL案例应用3

lower_bound实践

题目背景

计算机竞赛小组的神牛 V 神终于结束了高考,然而作为班长的他还不能闲下来,班主任老 t 给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是 v 神太忙了,身后还有一群小姑娘等着和他约会,于是他想到了同为计算机竞赛小组的你,请你帮他完成这个艰巨的任务。

题目描述

现有 m m m 所学校,每所学校预计分数线是 a i a_i ai。有 n n n 位学生,估分分别为 b i b_i bi。

根据 n n n 位学生的估分情况,分别给每位学生推荐一所学校,要求学校的预计分数线和学生的估分相差最小(可高可低,毕竟是估分嘛),这个最小值为不满意度。求所有学生不满意度和的最小值。

输入格式

第一行读入两个整数 m , n m,n m,n。

第二行共有 m m m 个数,表示 m m m 个学校的预计录取分数。

第三行有 n n n 个数,表示 n n n 个学生的估分成绩。

输出格式

输出一行,为最小的不满度之和。

输入输出样例 1
输入 1
复制代码
4 3
513 598 567 689
500 600 550
输出 1
复制代码
32
说明/提示

数据范围:

对于 30 % 30\% 30% 的数据, 1 ≤ n , m ≤ 1 0 3 1\leq n,m\leq10^3 1≤n,m≤103,估分和录取线 ≤ 1 0 4 \leq10^4 ≤104;

对于 100 % 100\% 100% 的数据, 1 ≤ n , m ≤ 1 0 5 1\leq n,m\leq10^5 1≤n,m≤105,估分和录取线 ≤ 1 0 6 \leq 10^6 ≤106 且均为非负整数。

题目分析

这是一道典型的二分查找题。我们需要为每个学生找到最匹配的学校(分数最接近的学校),计算不满意度(分数差的绝对值),并求和。

核心思路:
  1. 预处理:将学校分数线排序,以便后续二分查找
  2. 二分查找:对每个学生的估分,使用二分查找找到最接近的分数线
  3. 边界处理:需要考虑找不到大于等于该学生分数的情况(所有学校分数都低于学生分数)和所有学校分数都高于学生分数的情况
复杂度分析:
  • 时间复杂度:O((m+n)log m)
    排序O(m log m) + 每个学生二分查找O(n log m)
  • 空间复杂度:O(m+n)

代码实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;  // 定义数组最大长度
int m, n;                // m: 学校数量,n: 学生数量
int a[N], b[N];          // a[]: 学校分数线,b[]: 学生估分
long long ans;           // 总不满意度(使用long long防止溢出)

int main() {
    // 输入数据
    cin >> m >> n;
    for(int i = 1; i <= m; i++) cin >> a[i];  // 输入学校分数线
    for(int i = 1; i <= n; i++) cin >> b[i];  // 输入学生估分
    
    // 对学校分数线排序,便于二分查找
    sort(a + 1, a + m + 1);
    
    // 遍历每个学生
    for(int i = 1; i <= n; i++) {
        // lower_bound: 找到第一个大于等于b[i]的学校分数线位置
        int p = lower_bound(a + 1, a + m + 1, b[i]) - a;
        
        // 情况1: 所有学校分数都低于该学生估分
        // 此时选择最后一个学校(分数最高的)
        if(p == m + 1) {
            ans += b[i] - a[m];
        }
        // 情况2: 第一个学校分数就大于等于该学生估分
        // 此时选择第一个学校(分数最低的)
        else if(p == 1) {
            ans += a[1] - b[i];
        }
        // 情况3: 普通情况
        // 需要比较a[p](第一个≥b[i]的学校)和a[p-1](最后一个<b[i]的学校)
        else {
            ans += min(a[p] - b[i], b[i] - a[p - 1]);
        }
    }
    
    // 输出总不满意度
    cout << ans;
    return 0;
}

功能分析

算法流程:
  1. 数据读取:读取学校数量m、学生数量n,以及各自的分数
  2. 预处理:对学校分数线进行排序,这是二分查找的前提
  3. 二分匹配
    • 对每个学生的估分,使用lower_bound查找
    • lower_bound返回的是第一个大于等于目标值的元素位置
  4. 三种情况处理
    • 情况1(p==m+1):所有学校分数都低于学生分数,选最高分学校
    • 情况2(p==1):所有学校分数都高于等于学生分数,选最低分学校
    • 情况3(普通情况) :比较a[p](刚好大于等于)和a[p-1](刚好小于),选择差值更小的
关键点解释:
  • lower_bound的使用:返回第一个不小于目标值的位置
  • 边界处理:代码正确处理了找不到大于等于值和找到的位置在两端的情况
  • 差值的计算min(a[p]-b[i], b[i]-a[p-1])确保取绝对值最小的差值
示例分析(样例输入):
复制代码
学校分数:[513, 598, 567, 689] → 排序后:[513, 567, 598, 689]
学生1(500):p=1(513),选择513,差值为13
学生2(600):p=4(689),选择598,差值为2
学生3(550):p=2(567),选择513和567中更接近的567,差值为17
总不满意度:13+2+17=32

各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}
  • 一、CSP信奥赛C++通关学习视频课:
    • C++语法基础
    • C++语法进阶
    • C++算法
    • C++数据结构
    • CSP信奥赛数学
    • CSP信奥赛STL
  • 二、CSP信奥赛C++竞赛拿奖视频课:
    • 信奥赛csp-j初赛高频考点解析
    • CSP信奥赛C++复赛集训课(12大高频考点专题集训)
  • 三、考级、竞赛刷题题单及题解:
    • GESP C++考级真题题解
    • CSP信奥赛C++初赛及复赛高频考点真题解析
    • CSP信奥赛C++一等奖通关刷题题单及题解

详细内容:

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转


2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

3、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

  • 2025 csp-j 复赛真题及答案解析(最新更新)
  • 2025 csp-x(山东) 复赛真题及答案解析(最新更新)
  • 2025 csp-x(河南) 复赛真题及答案解析(最新更新)
  • 2025 csp-x(辽宁) 复赛真题及答案解析(最新更新)
  • 2025 csp-x(江西) 复赛真题及答案解析(最新更新)
  • 2025 csp-x(广西) 复赛真题及答案解析(最新更新)
  • 2020 ~ 2024 csp 复赛真题题单及题解
  • 2019 ~ 2022 csp-j 初赛高频考点真题分类解析
  • 2021 ~ 2024 csp-s 初赛高频考点解析
  • 2023 ~ 2024 csp-x (山东)初赛真题及答案解析
  • 2024 csp-j 初赛真题及答案解析
  • 2025 csp-j 初赛真题及答案解析(最新更新)
  • 2025 csp-s 初赛真题及答案解析(最新更新)
  • 2025 csp-x (山东)初赛真题及答案解析(最新更新)
  • 2025 csp-x (江西)初赛真题及答案解析(最新更新)
  • 2025 csp-x (辽宁)初赛真题及答案解析(最新更新)

CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

  • 129 道刷题练习和详细题解,涉及:模拟算法、数学思维、二分算法、 前缀和、差分、深搜、广搜、DP专题、 树和图

4、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
有为少年2 小时前
Welford 算法 | 优雅地计算海量数据的均值与方差
人工智能·深度学习·神经网络·学习·算法·机器学习·均值算法
Tim_103 小时前
【C++入门】04、C++浮点型
开发语言·c++
Ven%3 小时前
从单轮问答到连贯对话:RAG多轮对话技术详解
人工智能·python·深度学习·神经网络·算法
山楂树の3 小时前
爬楼梯(动态规划)
算法·动态规划
谈笑也风生3 小时前
经典算法题型之复数乘法(二)
开发语言·python·算法
hkNaruto3 小时前
【C++】记录一次C++程序编译缓慢原因分析——滥用stdafx.h公共头文件
开发语言·c++
智算菩萨3 小时前
强化学习从单代理到多代理系统的理论与算法架构综述
人工智能·算法·强化学习
lhn3 小时前
大模型强化学习总结
算法
Gigavision3 小时前
MMPD数据集 最新Mamba算法 源码+数据集 下载方式
算法