笨人小白的温故知新——二分法(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

MicroPython驱动ST7789屏避坑实录:从GB2312到完整中文字库的升级之路

本文详细介绍了使用MicroPython驱动ST7789显示屏实现完整中文字库显示的实战方案。从硬件选型到字库系统改造,再到内存优化和显示性能提升,提供了一套突破GB2312限制的全套中文显示解决方案,特别适合ESP32开发者在物联网设备中实现高质量中文显示。

weixin_29190573的博客 394

二分查找和二分答案模板

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

Sunny不要停的博客 1058

GraphRAG 踩坑记录

GraphRAG踩坑记录

yufanwenshu的博客 4351

[LaTeX] 调整参考文献的格式(References),包括作者名缩写,行距,字体,引用顺序等等

在此记录我对LaTeX中参考文献references的尝试,主要涵盖如题几个方面。

the Blog of 等不到天亮丶等时光 4万+

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

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

Ruially的博客 600

PCB激光直接成像(LDI)设备技术解析与优化方案

激光直接成像(LDI)是PCB制造中的关键数字化工艺,通过激光束直接在基板上形成电路图案。其核心技术在于高精度光学系统与智能控制算法的结合,工作精度可达微米级。在HDI板、柔性电路等高端PCB制造中,LDI技术能显著提升线宽精度和层间对位准确性。当前行业面临材料适配性、热变形控制等挑战,动态能量补偿、多波长曝光等创新方案正在突破这些瓶颈。随着模块化设计、预测性维护等工程实践的普及,LDI设备综合效率持续提升,为5G、汽车电子等领域的精密电路生产提供关键技术支撑。

weixin_29168393的博客 392

笨人小白的温故知新——递归(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

DaVinciCFG实战:从ARXML配置到ADC代码生成全解析

本文详细解析了使用DaVinciCFG工具进行ADC模块配置的全过程,从ARXML文件处理到代码生成与集成。重点介绍了关键参数配置、ARXML语法规则、常见错误排查及代码优化技巧,帮助开发者掌握AUTOSAR架构下ADC驱动开发,提升汽车电子系统的可靠性。

f9g0h的博客 378

OpenCV透视变换实战:5分钟搞定歪斜证件照矫正(附完整代码)

本文详细介绍了如何使用OpenCV的透视变换技术快速矫正歪斜证件照,包含完整的Python代码实现。通过特征检测、坐标计算和矩阵变换三个核心步骤,5分钟内即可将手机拍摄的歪斜图像自动矫正为专业级证件照,大幅提升图像处理效率。

weixin_29094979的博客 481

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

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

Ruially的博客 923

Java中使用工厂模式和策略模式优雅消除if-else语句(UML类图+案例分析)

在最近的后端开发中,多多少少会发现有很多if-else语句,如果条件过多则会造成整体代码看起来非常臃肿。本篇博客汇总了我对工厂模式和策略模式的理解,以及我是如何把它们巧妙运用在实际项目当中的一些技巧进行了分享,如有问题,欢迎评论区讨论!

黄团团的个人博客 2612

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

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

Ruially的博客 572

目标检测基础

目标检测是计算机视觉的核心任务,需同时对图像中的物体进行定位与识别。传统方法存在速度慢、精度低等问题,而深度学习显著推动了该领域发展,使实时高精度检测成为可能。检测的核心是为每个物体预测边界框坐标和类别标签。为实现高效检测,引入了锚框机制,通过预设多尺度、多宽高比的候选区域,缩小预测偏移量,提升定位精度。训练时,通过计算锚框与真实边界框的交并比 (IoU) 确定正负样本,并基于此生成类别标签和坐标偏移量作为监督信号。该方法提升了检测器对多尺度目标和复杂场景的鲁棒性。

盼小辉丶的博客 2755

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

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

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

Ruially的博客 555

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

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

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

Ruially的博客 462

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

笨人小白的温故知新——排序(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、付费专栏及课程。

余额充值