笨人小白的温故知新——二分法(1)

【C++】洛谷P1678烦人的高考志愿 第一次这么有成就感!立马写个题解贴记录一下(●ˇ∀ˇ●) 阅读详情

今天,通过B站的视频,解决了我对于区间的开闭的问题。

下面,我通过下面一道题来回顾一下。

P1678 烦恼的高考志愿


题目背景

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

题目描述

现有 m 所学校,每所学校预计分数线是 ai​。有 n 位学生,估分分别为 bi​。

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

输入格式

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

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

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

输出格式

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

输入输出样例

输入 #1复制

4 3
513 598 567 689
500 600 550

输出 #1复制

32

说明/提示

数据范围:

对于 30% 的数据,1≤n,m≤103,估分和录取线 ≤104;

对于 100% 的数据,1≤n,m≤105,估分和录取线 ≤106 且均为非负整数。


我的思路:

(1)为了方便给每一位同学选择大学,我选择用快速排序将大学的录取分数线进行升序操作。

(2)然后,给n[N]数组中的每一个同学的分数,选择大学。这里我采用了二分法来解决。

我用了两种二分法,区别在于区间的限定。

第一种:采用左闭右闭区间

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std ;
const int N = 1e6+10 ;
int m[N] , n[N] ;

void quick_sort(int a[] , int l , int r){
	if(l >= r)	return ;
	int i = l-1 , j = r+1 , x = a[l+r>>1] ;
	while(i < j){
		do i ++ ; while(a[i] < x) ;
		do j -- ; while(a[j] > x) ;
		if(i < j)	swap(a[i] , a[j]) ;
	}
	quick_sort(a , l , j) , quick_sort(a , j+1 , r) ;
}

int main(){
	int t , k ; cin >> t >> k ;
	for(int i = 1 ; i <= t ; i ++)	cin >> m[i] ;
	for(int j = 1 ; j <= k ; j ++)	cin >> n[j] ;
	quick_sort(m , 1 , t) ;
	
	long long ans=0;
	for(int i = 1; i <= k; i++)
	{
		int l = 1 , r = t ;//定义左边界与右边界
		while(l<=r)
		{
			int mid=(l+r)/2;//取查找范围的中间值
			if(m[mid]<n[i])//如果录取分数线数组中的第mid个元素小于或等于那位同学的分数
			{
				l = mid+1;//左边界就往右移
			}
			else
			{
				r = mid-1;//右边界就往左移
			}
		}
		if(n[i] <= m[1]){
    		ans += m[1] - n[i];
		}else if(n[i] >= m[t]){
    		ans += n[i] - m[t];
		}else{
    		ans += min(abs(m[r]-n[i]),abs(m[l]-n[i]));
		}
	}
	cout<<ans;//输出ans
	return 0;//结束程序
}

第二种:采用左开右开区间

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std ;
const int N = 1e6+10 ;
int m[N] , n[N] ;

void quick_sort(int a[] , int l , int r){
	if(l >= r)	return ;
	int i = l-1 , j = r+1 , x = a[l+r>>1] ;
	while(i < j){
		do i ++ ; while(a[i] < x) ;
		do j -- ; while(a[j] > x) ;
		if(i < j)	swap(a[i] , a[j]) ;
	}
	quick_sort(a , l , j) , quick_sort(a , j+1 , r) ;
}

int main(){
	int t , k ; cin >> t >> k ;
	for(int i = 1 ; i <= t ; i ++)	cin >> m[i] ;
	for(int j = 1 ; j <= k ; j ++)	cin >> n[j] ;
	quick_sort(m , 1 , t) ;
	
	long long ans=0;
	for(int i = 1; i <= k; i++)
	{
		int l = 0 , r = t+1 ;//定义左边界与右边界
		while(l+1<r)
		{
			int mid=(l+r)/2;//取查找范围的中间值
			if(m[mid]<=n[i])//如果录取分数线数组中的第mid个元素小于或等于那位同学的分数
			{
				l = mid;//左边界就往右移
			}
			else
			{
				r = mid;//右边界就往左移
			}
		}
		if(n[i] <= m[1])
		{
			ans += m[1] - n[i];
		}
		else if(n[i] >= m[t]) 
		{
			ans += n[i] - m[t];
		}
		else
		{
			ans += min(abs(m[l]-n[i]),abs(m[r]-n[i]));
		}
	}
	cout<<ans;//输出ans
	return 0;//结束程序
}

那么,你可能困惑了,怎么一会儿+1,一会儿不+1;一会儿>=,一会儿>的。

那么,你可以这样理解,这些都取决于让区间有效。

对于 [a , b] 这样的全闭区间,一定满足a <= b。例如:[2 , 2]是有效区间,只包含2这个元素。

对于(a , b)这样的全开区间,一定满足a+1<b。例如:(2,2)就是个无效区间,(2,3)也是(因为都是整数!)。

这样理解的话,就非常便于我们coding啦!

二分查找万能模板(基础版) 二分查找问题的一种万能模板 阅读详情

相关推荐

【洛谷】P1678 烦恼的高考志愿

洛谷 P1678 烦恼的高考志愿

m0_62531913的博客 944

二分答案(模板)

二分答案(模板)

qq_62767608的博客 1445

C#实战:如何从零构建一个轻量级软PLC梯形图编辑器(附完整源码)

本文详细介绍了如何使用C#从零开始构建一个轻量级软PLC梯形图编辑器。内容涵盖项目架构设计、GDI+图形渲染、编辑交互实现以及核心的扫描执行引擎开发,并提供了定时器、计数器等高级功能的实现思路与完整源码,为开发者深入工业自动化领域提供了实战指南。

4k5l6j7h8的博客 257

二分查找和二分答案模板

我个人比较喜欢第一个板子,接下来用第一个板子介绍一下浮点二分和二分答案。的mid计算方式不同,所以在编程过程中出错的概率更大。上面三个板子中比较好用的是第一个和第三个,第二个板子在。都只在各自的可行区移动,也就是说在。

Sunny不要停的博客 1058

保姆级教程:在ROS2 Humble上搞定Livox Mid-360雷达,从IP配置到Rviz点云显示

本文提供在ROS2 Humble上配置Livox Mid-360激光雷达的完整教程,涵盖从IP设置到Rviz点云显示的全流程。详细解析硬件连接、驱动编译、配置文件优化及常见问题排查,帮助开发者快速搭建开发环境并实现高效点云可视化。

weixin_30955617的博客 183

告别手动改代码!用SSC工具5分钟搞定EtherCAT从站动态模块配置(含Excel模板)

本文详细介绍了如何利用SSC工具和Excel模板实现EtherCAT从站动态模块配置的自动化流程。通过零代码修改的动态配置方案,大幅提升工业自动化产线的灵活性和效率,配置时间从平均4小时缩短至8分钟,错误率下降96%。文章包含Excel模板设计、实战演示和避坑指南,助力工程师快速掌握这一高效工具。

weixin_28339967的博客 570

笨人小白的温故知新——排序(1)

这次,我来分享一下我新学习的!网上有很多大佬整理了归并排序,并且超级厉害的做了动图。就是这个大佬的下面我想回顾总结一下我现在对归并排序的认识与理解,并且把它融入这道题中。

Ruially的博客 600

实战解析:如何通过LTspice仿真优化MOS管缓启动电路,解决上电冲击电流问题

本文详细解析如何通过LTspice仿真优化MOS管缓启动电路,有效解决上电冲击电流问题。文章从问题根源分析入手,介绍LTspice环境搭建、缓启动电路设计原理、参数优化技巧及实际工程问题排查,帮助工程师掌握MOS管电源开关电路的关键设计方法,提升系统可靠性和性能。

weixin_28683689的博客 515

笨人小白的温故知新——递归(1)

2*5是由10分解而来的,这时,我们很容易想到递归:20的分解数有一部分是10的分解数贡献的。因为要保证因数>=前一次分解出的因数,所以是fenjie(k/i,i)先通过分解20来找规律:20 = 20 = 2*10 = 4*5 = 2*2*5 共4种。因为最先提出来的因数小,所以k/i才有可能继续提出因子,所以k/i作为下一步要分解的数。20 = 2*10 = 10 *2,显然这是两种分解方法是同一种。每进行一次分解,就要保证因数>=前一次分解出的因数。但这个比较复杂,所以我参考了大佬的做法,现在开始~

Ruially的博客 403

【NVIDIA-B200 GPU固件升级】NVIDIA Blackwell B200 GPU 固件更新全指南

B200 GPU 固件更新并非 “执行一条命令即可” 的简单操作,而是涉及 “版本兼容性校验、BMC 环境准备、UEFI 引导、Redfish 协议交互” 的系统性工程。从文档翻译与技术解析来看,NVIDIA 的更新流程设计围绕 “安全” 与 “稳定” 两大核心 —— 无论是 0.9 版本的 “跳板限制”,还是 UEFI Shell 的引导要求,本质都是为了避免因操作不当导致硬件损坏。对于数据中心运维人员,建议在更新前做好三项准备:① 确认 GPU 当前固件版本(通过查询),规划升级路径;

jundao1997的专栏 742

excel 如何自动调整行间距 vba

EXCEL是一个非常使用的软件,虽然我们平时仅使用他做一些报表,仅此而已;我在工作中,由于很懒,不愿意做考试重复的工作,就想着使用vba的宏来完成重复的工作,这样就能省出一部分的时间来了。本人不喜欢在博客里面写以下教程类的东西,我的理念是将工作中的痛点的解决办法分享出来,以解决问题为主。

sixtome 1316

笨人小白的温故知新——递归(3)

我们把目光聚焦到第k位,让k、k+1、k+2······等位上的字母,均有机会坐到第k位上,而第k+1位、k+2位呢?那是下一个paixu()函数需要管的事,不归这一个函数管。(这就是我总是没有思路的原因,总是看着第k位上的,想着以后那些位该咋办)笨笨的我依旧没能做出来,仍然是参考大佬的做法,我现在来进行反思回顾大佬的思路,汲取经验。大佬的思路应该是:先固定当前位,再去固定下一位,直到所有的位置都被固定住。2)接着,3 => 2 => 1有着明显的递减规律,3是6的一半。针对第三个点,答案就很显然啦!

Ruially的博客 923

有趣的方式学习DDR5(4)—— DDR5 SDRAM 启动与初始化过程全攻略

🟢。

weixin_43199439的博客 1623

笨人小白的温故知新——递归(5)

了。首先定义,这个递归函数的主要作用是标记没有找到配对的“(”,只要发现了“(”,我们就调用这个奇妙的递归函数。只要我们发现了有“)”与之配对,我们就不标记“(”而这个递归函数,也可以保障有配对的“)”不会被标记。这个指针pin也很是精妙,它“继承”了k旧的值,并且可以帮助标记没有配对的“(”。因为递归就像多层大蛋糕,进行完一层后,会自动回到下一层。这段代码里也有很多我新学到的函数。下面是我查到的相关资料。1.fill():用一个给定值去填充所有元素。fill_n():用一个给定值填充前n个元素。

Ruially的博客 572

快速生成2D卡通人物的AI工具:开启Live2D角色创作的新时代

随着这一创新工具的推出,我们正见证着Live2D角色创作进入了一个全新的阶段。它不仅极大地简化了角色设计的过程,也为广大创作者提供了一种全新的表达方式。对于那些渴望将脑海中的构思迅速转化为现实的人来说,这无疑是一大福音。现在就访问项目主页,开始探索无限可能吧!t=O83A项目主页https://human3daigc.github.io/Textoon_webpage/

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 4833

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

笨人小白的温故知新——排序(3)

我来啦!今天依旧是的一题多解。(不厌其烦地附上题目)【题目描述】给定一个长度为N(不大于500)的正整数序列,请将其中的所有奇数取出,并按升序输出。【输入】第1行为 N;第2行为 N 个正整数,其间用空格间隔。【输出】增序输出的奇数序列,数据之间以逗号间隔。数据保证至少有一个奇数。【输入样例】10【输出样例】1,3,5,7,9方法四:冒泡排序我在大佬源代码的基础上,将q[j]与q[j+1]的复制与赋值换成了swap()函数!嘻嘻,我会a little bit举一反三了!

Ruially的博客 555

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

笨人小白的温故知新——递归(4)

其实本来是一段很简单的代码,但是这个题带给我的收获很大,所以我决定来做一个自己的反思回顾。来讲一下我做这道题遇到的问题(主要是解决运行超时的问题):1)我一开始并没有用记忆化,导致运行超时。2)我用了一个记忆化(但是是错的)!pell(k)试图判断返回值是否为 0,但pell(k)本身又会无限递归,永远无法执行到后续逻辑;你以为这就结束了?但是却运行超时了。why?

Ruially的博客 462

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

笨人小白的温故知新——排序(2)

这是一个一题多解的博客!题目描述】给定一个长度为N(不大于500)的正整数序列,请将其中的所有奇数取出,并按升序输出。【输入】第1行为 N;第2行为 N 个正整数,其间用空格间隔。【输出】增序输出的奇数序列,数据之间以逗号间隔。数据保证至少有一个奇数。【输入样例】10【输出样例】1,3,5,7,9方法一:插入法这就是插入法的代码模板。它的原理很简单,就是以一个乱序的数组中的第一个数为基石,通过后面的数与前面的数字比较,将数字逐一为它们找到自己的位置。

Ruially的博客 377

笨人小白的温故知新——递归(6)

这是一道很经典的题。当然,我一开始也没有做出来,但是!我当时发现了一些规律!只是当时不知道怎么表达而已(傲娇)。下图,是汉诺塔问题的抽象模型。

Ruially的博客 354

笨人小白的温故知新——递归(2)

这是一道比较简单的递归题,根据高中数学的排列组合知识很容易就能解决。

Ruially的博客 304

学习方式参考

需要庞大的知识体系面(形成自己的思维) ==>路漫漫其修远兮,吾将上下而求索 坚持下来 初期这个阶段,允许大家不理解就背(现在不理解,很大原因是,没找到状态,很多东西听不进去,还没有编程的意思,内心还在痛苦这玩意有啥用…;心不静,学的过程中会感觉烦躁;坐不住…) 1、把基础知识掌握扎实一些 2、培养大家的学习习惯 3、培养大家的研究能力,自学能力,实战开发能力 致知 诚意 正心 身修 ...

leizi929的专栏 217

【算法学习】二分查找与二分答案

二分可以简单分为二分查找与二分答案。:在一个有序的数组中进行搜索,时间复杂度为O(nlogn)。:在答案的一个范围内进行二分搜索。

Delicacy__的博客 1872

洛谷P1678 烦恼的高考志愿 —二分查找

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

m0_72522122的博客 642

二分答案(超级详细)

二分答案,超级详细,小学学历就懂

lijingheng66的博客 5351

二分查找:万能模板及详细例题

将木头按长度l切,使所有的木头切完后可以正好有k段,l越大越好,因此本题应该从l出发,枚举每种l的可能,找到恰好是不满足题意的那个点。:int: 2的30次方 long long:2的60次方,因此count需要开long long。要找到x的起始位置和结束位置,也就是要找到第一个不 x。思路:转换为A = B + C,枚举B,然后在数组中找A是否存在。方法1:枚举搬走哪块石头,但选择太多,一定会超时。方法2:枚举答案,即枚举最小跳跃距离,二分答案例题5:P2678-跳石头。

Villanelle_w的博客 2388

【算法笔记】二分查找 && 二分答案 (超详细解析,一篇让你搞懂二分)

二分查找应该算是是很多人入门的第一个算法吧,无论是ACM还是蓝桥杯都是必学的算法,很多人都觉得其非常简单,但它真的那么简单吗?Knuth 大佬(发明 KMP 算法的那位)曾说过:(思路很简单,细节是魔鬼)本文将为大家详细讲解二分查找的原理和使用场景并且,我们就是要深入细节,我将从while循环中该不该带mid该不该+1等地方分析这些细节的差异及出现差异的原因,保证你能灵活准确的写出二分查找算法。二分查找,也称为折半查找(Binary Search),是一种在有序数组中查找特定元素的搜索算法。

2302_79577794的博客 2万+
上一篇: 笨人小白的温故知新——排序(3)
下一篇: PTA天梯赛题集温故
Ruially
博客等级 码龄1年 60粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值